代码到可执行文件中间经历的过程

大致过程可分为以下4个步骤:

预处理->编译->汇编->链接

一、预处理

处理源代码文件以“#”开始的预编译指令。

1)展开宏定义

2)处理所有条件编译指令

3)处理#include预编译指令,递归地将被包含的文件插入进来

4)删除注释

5)添加行号和文件名标识,这样编译器产生错误和警告时才能显示行号

6)保留#pragma编译器指令

最终生成.i文件(c语言),或者.ii文件(C++语言)。

二、编译

1)扫描,将源代码输入到扫描器。

1)词法分析,将源代码的字符序列分割成一个个记号:关键字、标识符、字面量、特殊符号,如“(”是一个记号,变量i是一个记号。词法扫描工具:lex

2)语法分析,生成一棵结点为表达式的语法树,同时检查表达式是否合法,如括号不匹配、缺少操作符在这步可以检查出来。语法分析工具:yacc

3)语义分析,检查表达式是否有意义,如类型匹配、除0。为语法树中的所有结点标上类型。

4)源代码优化,如2 * 5,在这个期间就可以被确定,直接用10替换该表达式。在该步会将语法树生成中间代码(不包含数据的大小、变量地址、寄存器名字)。

5)目标代码生成,将中间代码生成目标机器代码。中间代码跟机器无关,目标机器代码跟机器有关,会标出字长、寄存器名字等。

6)目标代码优化,用位移代替乘法、删除多余的指令等。

最终会生成汇编代码文件。

三、汇编

将汇率代码转变为机器可以执行的指令。仅简单根据汇编指令和机器指令的对照表一一翻译,不做指令优化。

汇编器工具:as

四、链接

链接主要是处理各个模块相互引用的部分,使得它们能正确衔接。比如A模块引用了B模块的某个函数、C模块的某个全局变量等。

1)地址和空间分配

2)符号决议(也叫地址绑定)

3)重定位。有些全局变量或函数定义在其它库中,重定位找到它们的地址。

发布了181 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43461641/article/details/105074671