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

本文详细解析了程序从源代码到最终运行的全过程,包括预处理、编译、汇编及链接等关键步骤,并深入探讨了各阶段的具体操作和技术要点。

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

预处理:

(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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值