编译、链接与装载学习笔记(一):源代码生成可执行文件的过程

源代码生成可执行文件经历预编译、编译、汇编和链接四个步骤。预编译处理宏定义、条件编译和头文件,生成.i文件;编译阶段进行词法、语法和语义分析,产生.s文件;汇编将语法树转为汇编代码,优化后生成.o文件;链接阶段整合目标文件和库,完成地址分配和符号决议,形成最终的.exe或.out文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源代码生成可执行文件的过程

一般从源代码到最后生成可执行文件需要经过四个步骤:

预编译–编译–汇编–链接

四个环节各自生成 :

.i文件 --> .s文件 --> .o文件 --> .out文件
               .exe文件

预编译
编译
汇编
链接
与其他的.o文件
静态库.a /动态库.so
源文件.c
源文件.i
文本
源文件.s
文本
源文件.o
二进制
源文件.out
二进制

预编译

查看预编译文件命令:

gcc -E 源文件.c -o 源文件.i

预编译的主要工作:

  • 处理宏定义 #define,注意空格的加入,以及不要加分号
  • 处理条件编译 #if #endif
  • 处理头文件 #include,将包含的文件插入到该预编译指令的位置
  • 删除注释 // ; /*
  • 添加行号与文件名
  • 保留所有的#pragma编译器指令,因为编译器需要使用它们

编译

编译的主要工作:

  1. 词法分析:使用有限状态机的算法,由扫描器扫描字符序列顺序生成一系列的符号,如:a = (b+c) --> a,=,(,b,+,c,)
  2. 语法分析:利用上下文无关语法(CFG)等方法,将词法分析得到的一系列符号生成对应的语法树
  3. 语义分析:主要进行类型声明、匹配和转换,判断定义是否循环引用等,是静态语义的分析;动态语义是在运行期判断的,如0不能作为除数等

生成语法树如:

=
a
+
b
c

语义分析后:

=
a
integer
+
b
integer
c
integer

汇编

查看汇编文件命令:
gcc -S 源文件.c -o 源文件.s

也可以反汇编查看汇编代码:

objdump -d xx.out或者.o,.a,.so等二进制文件

语义分析后会将语法树生成中间代码,如三地址码,然后三地址码根据目标机器生成对应的目标汇编代码;汇编代码优化器会将目标汇编代码优化(如:常量表达式运算1+2后得到一个全新的常量3,使用位移来代替乘法运算等),然后输出目标二进制文件

汇编代码转换成机器代码指令,原则上两组指令一一对应

链接

将目标文件,静态库或者动态库,链接成可执行文件
完成各个编译单元(模块)的拼接

链接的主要工作:

  • 地址和空间分配:为目标文件中已定义符号分配内存以及地址
  • 符号决议(符号绑定):保证每个目标文件所有引用,声明都能在自身或其它目标文件中能找到唯一的定义,若声明符号未找到定义则报错
  • 重定位:所有已声明未定义的符号重新定位地址
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值