程序执行期间发生了哪些事——预处理,编译,汇编,链接

来源:互联网 发布:淘宝号权重查询 编辑:程序博客网 时间:2024/05/16 12:09

当我们运行一个程序时,究竟发生了什么,这篇博客,我将就我的了解做出分析。

预处理:

(1)将所有的"#define"删除,展开宏定义。

(2)处理条件预编译指令,如:"#if" "ifdef"  "endif" 

(3)将被包含的文件插入到"#include"预编译指令中

(4)删除注释

(5)添加行号,以便编译器产生调试用的行号和用于编译产生错误时的警告的行号

(6)保留所有的#pragma编译器指令

编译:

编译一般可以分为6个步骤:

扫描:扫描整个代码部分,产生记号,记号主要有:关键字,标识符,字面量(数字,字符串),特殊符号(加号,乘号)

语法分析:确定运算符的优先级(乘法高于加法,圆括号高于乘法),符号的多重含义(*)。如果出现语法错误(括号不匹配,缺少操作符),编译器就会报错。

经过语法分许之后,它会生成下图的树。


语义分析:源代码被扫描过后,编译器所能分析的语义是静态语义。静态语义通常包括声明和类型的匹配,类型的转换。动态语义一般是指在运行期间出现的语义相关的问题,比如0作为除数和分母是一个运行期语义错误。

经过语义分析后,上图整棵数的表达式都被表示了类型,如果有需要隐式转换,树上会被插入相应的转换节点。

源代码优化:源代码级别有一个很重要的优化——源码级优化器。比如上图中的(2+6)就会被优化成8。

源代码优化器会将整个语法树转换成中间代码。比较常见的中间代码有三地址:x = y op z,这里的op操作可以是加减乘除。

代码生成:代码生成的阶段属于编辑器后端,主要包括代码生成器目标代码优化器 。代码生成器在代码生成阶段将中间代码转换成目标机器代码。

目标代码优化:生成的目标机器代码再由目标代码优化器进行优化。比如选择合适的寻址方式,使用移位来代替乘法运算,删除多余的指令等。

汇编:

汇编器将汇编代码转变成机器可以执行的指令,每一个汇编语言对应一条机器指令。

链接:

把每个源代码模块独立的编译,然后按照要求将它们组装起来,使各个模块能够正常的衔接,这个组装的过程就是链接。

链接过程主要包括地址和空间分配,符号决议和重定位这些步骤。

源代码(.c)经过编译器编译成目标文件(.o 或 .obj)

阅读全文
0 0
原创粉丝点击