编译过程包括四个步骤:
1、预处理
2、编译
3、汇编
4、链接
一、预处理
预处理阶段主要处理一些预处理指令,比如文件包括、宏定义、条件编译。
1、文件包括
就是将原有的#include头文件替换成真正的内容
2、宏定义
预处理时需要把所有宏定义替换成真正的内容
3、条件编译
预处理时会对条件编译指令决定哪个程序需要编译,哪些不需要编译
二、编译
编译阶段进行语法分析、词法分析和语义分析,并且将代码优化后产生相应的汇编代码文件(ASCLL文件),即.s 文件。这个过程是整个程序构建的核心部分,也是最复杂的部分之一。
三、汇编
通过不同平台(Windows、Linux)的汇编器将汇编代码翻译成机器码,即生成二进制可重定向文件(.o)。
任何一个源文件在进行编译阶段的时候会去产生符号表,符号表中存放的就是程序所产生的符号(例如:函数名,变量名等),我们的编译阶段是不会去给符号分配正确的地址。这些符号都没有被分配地址,因此.o文件没有经过链接是无法执行的。
四、链接
(1)第一步:由于每个.o文件都有都有自己的代码段、bss段,堆,栈等,所以链接器首先将多个.o 文件相应的段进行合并,建立映射关系并且去合并符号表。进行符号解析,符号解析完成后就是给符号分配虚拟地址。
(2)第二步:将分配好的虚拟地址与符号表中的定义的符号一一对应起来,使其成为正确的地址,使代码段的指令可以根据符号的地址执行相应的操作,最后由链接器生成可执行文件。
gcc:
预处理 gcc -E main.c -o main.i
编译 gcc -S main.i -o main.s
汇编 gcc -c mian.s -o main.o
链接 gcc main.o -o app