一个.c文件最终成为a.out文件需要经历预处理,编译,汇编,链接这4个过程。
gcc总过程如下
预编译
解释
主要处理源代码文件里以#开始的预编译指令。eg.#include,#define
内容
1.展开所有的宏定义,#define
2.处理所有条件编译指令,#if, #,ifdef,#elif,#else,#endif
3.处理#include,通过递归过程,把被包含的文件插入到预编译指令的位置.
4.删除所有注释,// 和 /* */.
5.添加行号和文件标识
6.保留所有#pragma编译器指令
编译
解释
通过一系列词法分析,语法分析,语义分析和优化最终生成相应汇编代码文件。
内容
1.词法分析:lex程序进行词法扫描
2.语法分析:将语句生成语法树
3.语义分析
* 动态语义* : 运行期间才能确定的语义
静态语义:编译期间能确定的语义,如声明和类型匹配。
4.优化和中间代码的生成
源码级优化器会在源码级别进行代码优化,比如(2+6)因为编译器这个值是确定的。
汇编
解释
通过汇编器as把汇编代码直接翻译成机器可以执行的指令,然后输出.o文件
这里有两个过程。
代码生成器:为机器产生属于自己的目标机器代码。
目标代码优化器:对代码生成器产生的代码进行优化。比如选择合适的寻址方式。
经过汇编过程的代码并不是真正的可执行代码,只是成为目标代码。因为比如malloc的数组地址,函数的确定地址等在程序没有执行的时候,是绝对不会提前知道的。因此必须进行链接过程。才能生成最后真正可执行的文件。
链接
解释
每个模块单读编译并组装的过程
内容
地址和空间的分配:
符号决议:
重定位:
/以上这三个是后面的内容/
容易忘的名词
cpp :预编译器
cpp :编译器
as :汇编
ld :链接
gcc:是对上述整个过程的一个封装包。
三地址码(Three-address Code):源码级优化器把语法树转换成中间代码,三地址码是中间代码的一种.记作c = a op b。op是对a 和b的综合操作。
重定位:目标代码中某目标地址是x,链接过程中这个地址被真实的函数的真实地址y赋值.这个地址修正的过程叫重定位。
重定位:
http://baike.baidu.com/link?url=pvqLg4_G7IflerZPnJ9lfx9QF_l3I8m6pNHB8WEUruVsIf4W_jAJmpZzl6jtLE1Vy3Xnlz1crUhXTfeiAqgMuPBipn3BA89jFzx4NVg9-renCjK9WPkrx9SxspaIVm-b
That’s all.