C 编译过程
C 语言使用 gcc 编译
$gcc hello.c
$./a.out
hello world
此过程可以分为四个步骤:预处理prepressing,编译compilation,汇编asembly,链接linking。
1.预编译过程
将源代码与头文件预编译为 .i 文件。C++中可能为.ii
$gcc -E hello.c -o hello.i (-E表示只进行预编译)
或者
$cpp hello.c > hello.i
预编译过程主要处理源代码文件中的以“#”开头的预编译指令。如“#include” "define"
(1)将所有的#define删除,并且展开所有的宏定义
(2)处理所有条件预编译指令,如#if #ifdef。。。#else
(3)将#include的文件插入到该条指令的位置。注意,这个过程是递归进行的。逐层将所有的#include插入
(4)删除所有注释 //和/**/
(5)添加行号和文件名标识,以便于编译时编译器产生调用时的行号信息,编译时产生编译错误或警告时显示行号。
(6)保留所有的#pragma指令。
2. 编译
编译过程是把预处理后的文件进行一系列词法分析,语法分析,语义分析及优化后生产相应的汇编代码文件。
$gcc -S hello.i -o hello.s
将预编译过程与编译过程合并一个步骤命令为:
$cc1 hello.c
或者
$gcc -S hello.c -o hello.s
3.汇编
汇编器是将汇编代码转化为机器可以执行的指令。
$as hello.s -o hello.o
或者
$gcc -c hello.s -o hello.o / $gcc -c hello.c -o hello.o
4.链接
将目标文件链接成可执行程序
$ld -static *.o -static-group -lgcc -lgcc_eh -lc -end-group *.o
编译过程:扫描,语法分析,语义分析,源代码优化,代码生成,目标代码优化。
语义分析包括静态语义分析和动态语义分析:
静态语义分析包括声明和类型的匹配,类型的转换。
动态语义分析是在运行期间的语义问题。
源代码优化器在生成中间代码过程中,会对语法树进行一定优化,如“2+6” 表达式优化为“8”
目标代码优化器,对目标代码进行优化,包括选择合适的寻址方式,使用位移代替乘法运算,删除多余指令等