一些集成IDE隐藏了处理的细节,其实一个程序的编译大体上可以分为如下几个步骤:
预处理->编译->汇编->链接
预处理:产生.i文件
gcc -E hello.c -o hello.i
cpp hello.c > hello.i
1。展开所有的 宏定义
2。处理所有的 条件编译指令
3。处理 #include指令,将文件包含进去
4。删除所有的 注释
5。添加 行号和文件标识
6。保留所有的#pragma编译器指令,编译器需要使用到
编译:
gcc -S hello.i -o hello.s
进行 词法分析、语法分析、语义分析以及优化后生成汇编代码
可以把预处理和编译合并,使用cc1的程序完成这一步骤
/usr/lib/gcc/i486-linux-gnu/4.1/cc1 hello.c
gcc命令可以说是一大堆后台程序的包装,根据不同参数调用相应的程序
汇编:
gcc -c hello.c -o hello.o
将汇编代码转为机器可以执行的指令, 直接翻译即可,可以使用汇编器as
as hello.s -o hello.o
链接:
将所有文件拼接在一起
编译的过程
1.词法分析:
将源代码输入到扫描器,运用 有限状态机将字符序列分割为一系列的 记号,包括关键字、标识符、字面量和特殊符号,同时生产符号表和文字表等
2.语法分析
对记号使用 上下文无关文法分析进而产生 语法树,语法树就是以表达式为节点的树。
3.语义分析
编译器分析的其实是静态语义,包括申明和类型的匹配、类型的转换,将语法树的 每一个表达式节点全部标上了类型
4.中间语言生成
源代码优化器将语法树转为 中间代码,是语法树的顺序表示,中间代码可以是 三地址码。同时,中间代码将编译器分为前端和后端,前端负责生成机器无关的中间代码,后端负责将中间代码转为目标机器代码。
5.目标代码生成与优化
属于 编译器的后端,包括代码生成器和目标代码优化器,代码生成器将中间代码转为目标机器代码,这一过程依赖于目标机器,目标代码优化器对代码进行优化。
静态链接:
将源代码模块分别编译之后,需要将它们组装起来,组装模块的过程就是链接。与早期程序猿手工调整地址本质上没有区别。链接过程主要包括 地址和空间分配、符号决议、重定位。