总结之预编译、编译、汇编、链接

预编译

生成预编译文件(.i文件)
gcc -E hello.c -o hello.i
处理规则:
1.将所有的#define删除,并展开所有的宏定义。
2.处理条件预编译指定,如#endif、#if、#elif等
3.处理#include预编译指令(这个过程是递归的)
4.删除注释
5.添加行号和文件标识
6.保留#pragma编译器指令
因为经过预编译后的.i文件不包括任何宏定义,所以当无法判断宏定义是否正确或头文件包含是否正确时,可以查看预编译后文件从而确定问题

编译

生成汇编输出文件(.s文件)
gcc -S hello.i -o hello.s
处理规则:
1.词法分析:源代码程序被输入扫描器(Scanner),扫描器通过运用一种类似于有限状态机(Finite State Machine)的算法,将源代码的字符序列分割成一系列的记号。这些记号可以分为关键字、标识符、字面量(包含数字、字符串等)和特殊符号(如加号、等号)。
2.语法分析:语法分析器(Grammar Parser)将对由扫描仪产生的记号进行语法分析,从而产生语法树(Syntax Tree)。
1.分析过程采用上下文无关语法的分析。
2.由语法分析器生成的语法树是以表达式为节点的树。

3.语义分析:由语义分析器(Semantic Analyzer)完成。编译器所能分析的语义是静态语义(Static Semantic),所谓静态语义是指再编译期可以确定的语义,与之对应的是动态语义(Dynamic Semantic)就是只有在运行期才能确定的语义。
4.源代码优化:源码级优化器(Source Code Optimizer)会在源代码级别进行优化。因为直接在语法树上做优化比较困难,所以源代码优化器往往将整个语法树转换成中间代码(Intermidediate Code)
1.中间代码有很多类型,在不同的编译器中有不同的形式,常见的有:P-代码和三地址码
2.中间代码使得编译器可以被分为前端和后端。编译器前端负责产生机器无关的中间代码,编译器后端将中间代码转换成目标机器代码。

5.目标代码生成和优化:编译器后端主要包括代码生成器(Code Generator)和目标代码优化器(Target Code Optimizer)。
代码生成器将中间代码转换成目标机器代码,目标代码优化器将目标代码进行优化,比如选择合适的寻址方式、使用位移来代替乘法运算、删除多余的指令等。

汇编

生成目标文件(.o文件)
gcc -c hello.s -o hello.o
汇编器将汇编代码转换成机器可以执行的指令。

链接

生成可执行文件
gcc hello.o - o hello
链接的主要内容:把各个模块之间相互引用的部分都处理好,使得各个模块之间能正确地衔接。
处理步骤:
1.合并段和符号表
2.符号解析:在符号引用的地方找到符号定义的地方
3.分配地址和空间
4.符号的重定位(Relocation)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值