被隐藏的构建过程

编译和链接

集成开发环境(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)

原文地址:https://www.cnblogs.com/fr-ruiyang/p/9683255.html