当前位置: 首页 > news >正文

【linux】基础开发工具(3)gcc/g++,动静态库

c/c++源代码到可执行程序“四级跳”

作为c/c++开发者,理解编译的过程至关重要,理解c/c++从代码一步步编译成可执行程序的过程是我们学习的必经之路。

.c/.cpp源代码到可执行程序,需经历预处理、编译、汇编、链接四个阶段,每一步都决定了程序的最终形态:

1.预处理:“文本替换” 的预处理
  • 处理#include(展开头文件)、#define(宏替换)、条件编译指令等,生成.i文件。
  • 示例命令:gcc -E code.c -o code.i

执行完成后生成一个.i文件。

2. 编译:“高级→汇编” 的翻译
  • 将预处理后的代码转换为汇编语言.s文件)。
  • 示例命令:gcc -S code.i -o code.s

编译先将代码编译为了汇编语言,为什么不直接编制成机器码呢?

我们的每一步都是基于前人走出来来的,最开始的编程就是纯二进制纸带打孔(孔洞能否被光透过代表0和1),但是这样操作繁杂效率低下且人类不容易理解。

在此之上,二十世纪四五十年代,汇编语言被发明出来,汇编相比二进制更容易被人理解。但是无法被机器理解。由此编译器产生了。

汇编的第一代编译器必然是用机器语言(二进制)实现的,因为汇编语言没有编译器就不能被机器识别,所以用二进制写了一个解析汇编语言的程序叫编译器。

直接将高级语言翻译成二进制(机器码)成本会非常高,汇编语言可以作为一个中间的跳板,但是现代语言中,这已经不是必然选项。这其中还有很多细节,本文不再赘述。

编译器的自举

有了二进制的第一代编译器之后,就可以用汇编语言实现自己的编译器,这一个过程叫做编译器的自举。

3. 汇编:“汇编→机器码” 的转化
  • 将汇编代码转换为机器码.o目标文件),这是计算机能直接执行的二进制指令。
  • 示例命令:gcc -c code.s -o code.o

注意:

.o文件虽然是机器码,但是默认不带可执行的属性。要想生成可执行程序,要将.o文件转化为可执行程序。

.o文件可以形成可执行文件,多个.o文件可以链接形成一个可执行程序(不同功能的代码分开编译,最终形成一个可执行文件)。

4. 链接:“目标文件→可执行程序” 的合并

将多个.o文件、依赖的库文件 “合并” 成可执行程序。

静态链接:把静态库的代码直接拷贝到可执行程序中。

静态链接在编译时就会完成链接,大体分为以下七步:

1.收集目标文件:解释编译器将文件编译成目标文件(.o或.obj)。

2.解析符号:链接器扫描所有目标文件,构建一个全局符号表,记录每个符号的定义位置。如果同一个符号被多次定义,链接器会报错(除非是弱符号)。如果某个符号未定义,链接器会从静态库中查找。

3.提取库文件:链接器按照命令行指定的顺序处理静态库。当遇到未解析的符号时,链接器会在静态库中查找包含该符号定义的目标文件,并将其加入到链接中。这个过程可能会重复,因为库中的目标文件可能又引用了其他符号。

4.合并段:链接器将每个目标文件中的代码段(如.text)合并到可执行文件的代码段,数据段(如.data、.bss)合并到数据段。同时,链接器会为每个段分配运行时内存地址。

5.重定位:在目标文件中,对于外部函数和变量的引用通常是暂时用相对地址或0地址表示。链接器根据符号的实际地址修改这些引用,填上正确的地址。重定位信息存储在目标文件的重定位表中。

6.生成可执行文件:完成重定位后,链接器生成可执行文件,其中包含程序运行的所有代码和数据,以及程序入口点信息。

动态链接:可执行程序仅记录动态库的 “引用”,运行时才加载库。

动态链接发生在运行时,但链接过程实际上分为两个阶段:编译时链接和运行时链接。

编译时链接(生成可执行文件时):
  1. 符号解析:与静态链接类似,链接器解析程序中的符号引用。但是,对于动态库中的符号,链接器不会将代码复制到可执行文件中,而是记录这些符号的名称和它们所在的动态库信息。
http://www.jsqmd.com/news/824551/

相关文章:

  • CLIP-as-service正则化终极指南:如何用Dropout和WeightDecay提升模型性能
  • 逆向思路解析:.m3u8.sqlite文件是如何被‘锁’住的?我们又该如何‘解锁’成视频?
  • 如何用.htaccess打造高性能新闻资讯平台:10个终极配置技巧
  • 终极指南:ChatGPT for Google扩展的自动化部署脚本完全解析
  • Simulink里三种TD微分器怎么选?用带噪声的正弦信号实测给你看(附模型)
  • 质量好到出圈!2026广州晶石石英式动态称重传感器,检测精度远超标准 - 品牌速递
  • 书成紫微动,律定凤凰驯:不是巧合,是海棠山铁哥与千古谶语的天然同频
  • Chrome for Testing架构深度解析:构建可靠浏览器自动化测试的3个核心设计
  • 2024年度终极指南:fg-data-profiling 数据质量监控与探索性数据分析工具深度解析 [特殊字符]
  • Windows系统提权迷局:一不小心掉进“空格陷阱”
  • windows-dev-box-setup-scripts在教育场景中的应用:快速部署学生开发环境
  • CMake嵌入式开发终极指南:交叉编译与资源受限环境实践
  • 三维姿态表达:从欧拉角、旋转矩阵到四元数的工程实践
  • Primer CSS骨架屏终极指南:10个实用技巧优化内容加载体验
  • SSVEP脑机接口入门:为什么说CCA算法是新手友好型‘神器’?(含与P300、运动想象的对比)
  • Simulink模型测试避坑指南:为什么你的Test Manager结果总对不上?(排查输入步长与表格配置)
  • 掌握Lua的基本数据类型:入门必备基础
  • 编程统计不同健身方式消费,减脂健康效果数据,推荐低成本居家健身方案,免去高额健身房消费。
  • 【软考高级架构】论文范文11——论信息系统的安全性与保密性设计
  • 告别烦人黑窗口!QT Creator控制台程序输出完美嵌入IDE的两种方法
  • TDesign小程序模板实战:从零构建首页布局与样式
  • 终极yargs容器化指南:3步实现Docker与CLI应用快速部署
  • 书成紫微动,律定凤凰驯:《第一大道》破局,《凰标》立规,铁哥的道韵流转
  • Notepad--终极指南:10个高效技巧掌握国产跨平台文本编辑器
  • 当你的Windows内核被凝视时,你已经一丝不挂
  • 2026年严选:质量好的墙砖厂商 - 品牌推广大师
  • 书成紫微动,律定凤凰驯:《第一大道》如何撕碎文化圈的资本垄断
  • AI驱动个人网站生成器:基于Next.js与OpenAI的配置化数字名片
  • Windows系统提权揭秘:玩转SC服务提权的“黑魔法”与“防身术”
  • 从YOLOv8到Heatmap:手把手教你搭建一个景区人员拥挤预警系统(含完整代码)