预编译
gcc -E hello.c -o hello.i
主要处理源代码文件中以#开始的预编译指令。比如#include、#define
- 将所有的#define删除、并展开所有宏定义
- 处理#include,将包含的文件插入到该预编译指令的位置。(这个过程是递归进行的)
- 删除所有的注释
- 添加行号和文件名标识,以便于编译时编译器产生调试用的行号信息及编译错误或警告时能够显示行号。
编译、汇编
gcc -S hello.i -o hello.s
编译:语法分析、语义分析。将高级语言翻译成机器语言的一个工具如汇编或机器指令。
gcc -c hello.s -o hello.o
汇编:将汇编代码转化为目标文件。
目标文件:至少要有编译汇编后的机器指令代码、数据,除了这些内容,目标文件还包括了链接时所需要的一些信息,比如符号表(链接时只关心里面的全局符号)、重定位表。
“.real.text"是针对”.text"段的重定位表,因为".text"段中至少有一个绝对地址的引用。而"data"段没有引用的话,就没有针对"data"段的重定位表".real.data"
链接
链接主要内容就是把各个模块之前相互引用的部分处理好,实质就是将地址重定位。
静态链接:ld a.o b.o -e main -o ab.out
动态链接: 不仅节省内存,还可以减少物理页面的换入换出,也可以增加CPU缓存的命中率,因为不同进程的数据和指令访问都集中在了同一个共享模块上。
动态链接就是把链接的过程本来从装载前推迟到了装载的时候。