被隐藏的构建过程

编译和链接

集成开发环境(IDE)一般将编译和链接的过程一步完成,这个过程叫做构建(Bulid),也有人翻译成生成.

构建的过程:

预处理(Prepressing)→编译(Compilation)→汇编(Assembly)→链接(Linking)

预编译

预编译过程主要处理那些源代码文件中的以#开始的预编译指令.主要处理规则如下

1.删除#define,展开所有宏定义

2.处理所有条件预编译指令

3.处理#include,将被包含的文件插入到该预编译指令的位置(递归进行)

4.删除所有注释

5.添加行号和文件名标识,便于编译时错误\警告\调试信息显示行号

6.保留所有#pragma指令

编译

词法分析:扫描器(Scanner)运用一种类似于有限状态机(Finite State Machine)的算法将源代码分割成一系列的记号(Token)

记号可以分为以下几类:关键字\标识符\字面量\特殊符号.

语法分析:语法分析器(Grammar Parser)采用上下文无关语法(Context-free Grammar)的分析手段产生语法树(Syntax Tree)

语法树:一种以表达式(Expression)为节点的树

语义分析:语义分析器(Semantic Analyser)能分析静态语义(Static Semantic)动态语义(Dynamic Semantic)

静态语义是在编译器可以确定的语义,通常包括声明和类型的匹配,类型的转换.

动态语义是只由在运行期才能确定的语义.

中间语言生成:源码级优化器(Source Code Optimizer)将整个语法树转换成中间代码(Intermediate Code)

它是语法树的顺序表示,已经非常接近目标代码了,但它一般跟目标机器和运行时环境是无关的.

中间代码由很多类型,不同编译器有着不同的形式,比较常见的有三地址码(Three-address Code)P代码(P-Code)

目标代码生成与优化:代码生成器(Code Generator)将中间代码转换成目标机器代码,这个过程十分依赖于目标机器,因为不同的机器有着不同的字长\寄存器\整数数据类型和浮点数数据类型等

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

 

对于不同的编程语言,编译器开发者只需改变词法和语法规则

不同编译器的源码级优化器可能有不同的定义或有一些其他的差异

高级编程语言的复杂导致编译器结构复杂

计算机CPU的复杂导致编译器的机器指令优化过程复杂

支持多种硬件平台导致编译器的指令生成过程复杂

汇编

汇编代码转变成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令.只需要根绝汇编指令和机器指令的对照表一一翻译即可.

链接

 主要解决模块之间如何通信的问题

最常见的属于静态语言的C/C++模块之间通信有两种方式:模块间的函数调用和模块间的变量访问。

都可以归结为一种方式:模块间符号的引用

链接过程主要包括:地址和空间分配(Address and Storage Allocation)符号决议(Symbol Resolution)重定位(Relocation)

 

posted @ 2018-09-27 17:14  睿阳  阅读(190)  评论(0编辑  收藏  举报