编译和链接过程
程序从源代码到可执行程序,一般包括四个步骤:预处理、编译、汇编和链接。
预处理
将.c文件生成一个对应的.i文件:
- 将宏定义替换“#define”
- 处理所有的条件编译指令,如“#if”、“#ifdef”等
- 处理“#include”预编译指令,将头文件插入到相应位置
- 删除所有的注释
- 添加行号、文件名标识,方便后边编译时,编译器产生编译相关的信息,如编译错误时显示行号等。
- 保留#pragma编译伪指令,因为后续编译时需要使用它们
编译
将.i文件生成一个对应的.s文件
编译过程时整个程序构建的核心,编译成功,会将源代码转换为汇编语言,编译的过程就是把.i文件进行一系列的词法分析、语法分析、语义分析以及优化,从而最终生成相应的汇编代码文件。
- 词法分析
将代码分割成一个个记号序列,如关键字、标识符、符号、变量等,保存到一个表中。 - 语法分析
将上一步生成的记号序列,根据语法规则形成语法树。 - 语义分析
分析语义是否有意义。如两个指针相乘,这显然是没有意义的,然后提示错误。又例如将浮点数赋值给整形数,则会默认进行类型转换,同时给出警告等。 - 代码优化
如某些情况下的循环展开,const数据的提前计算(2+3则会提前计算为5),删除没有用的语句等,然后生成汇编语言。
汇编
汇编器(as)将汇编代码转变为机器码,每一条汇编语句几乎都对应一条机器指令。最终会生成.o文件。
链接
链接的主要工作就是将各个模块之间相互引用的部分正确的衔接起来。链接的过程主要包括了地址和空间分派、符号决议和重定向。
同是寒窗苦读,
怎愿甘拜下风,
我可以一落千丈,
但我偏要一鸣惊人。