编译

编译和链接

编译过程

预编译

生成.i 文件 不包含任何宏定义,宏被展开

编译

汇编

链接

编译器做了什么

词法分析

有限状态机算法可以将源代码的字符序列分割成一系列的记号。

array[index] = (index + 4) * (2 + 6) 
编译_第1张图片
image

词法分析一般包括:关键词、标识符、字面量(包含数字、字符串)和特殊符号(加号、等号)

语法分析

对词法分析的记号进行语法分析,产生语法树,树的节点是表达式。语法层面的分析,并不了解这个语句是否真正有意义。

                  assignExpression

   SubscriptExpression[]           MultipicativeExpression *
 
Identifier          Identifier       Additive               Additive
Expression         Expression        Expression(+)        Expression(+)
array               index
                                Identifier  Number    Number       Number
                                 Index         4       2             6

语义分析

语法分析仅仅是完成了对表达式的语法层面的分析,但是它并不了解这个语句是否真正有意义

静态语义

编译期可以确定的语义,包括声明和类型的匹配,类型的转换。比如当一个浮点型的表达式赋给一个整形的表达式时,其中隐含了一个浮点型到整形的转换的过程,语义分析过程中需要完成这个步骤,

动态语义

运行期可以确定的语义,程序运行期出现的语义相关的问题。
经过语义分析阶段以后,整个语法树的表达式都被标识了类型,如果有些类型需要做隐式转换,语义分析程序会在语法树中插入相应的转换节点,

编译_第2张图片
image

中间语言生成

在源代码级别有一个优化过程,源代码优化器会在源代码级别进行优化,(2 + 6)这个表达式可以被优化,因为它的值在编译器就可以被确定。

目标代码生成与优化

movl index, %ecx;  value of index to ecx
addl $4, %ecx  ; ecx = ecx + 4
mull $8m %ecx  ; ecx = ecx * 8
movl index %eax ; value of index to eax
movl %ecx,array(,eax,4) ; array[index] = ecx

最后目标代码优化器对上述的目标代码进行优化,比如选择合适的寻址方式、使用位移来代替乘法运算、删除多余的指令等。上面的例子中,乘法由一条相对复杂的基址比例变址寻址的lea 指令完成,随后由一条mov 指令完成最后的赋值操作,这条mov指令的寻址方式与lea是一样的。

movl  index, %edx
leal 32(,%edx, 8), %eax
movl %eax,array(,%edx, 4)

模块拼装 - 静态链接

人们把每个源代码模块独立编译,然后按照需要将他们“组装”起来,这个组装模块的过程就是链接,链接的主要内容就是吧各个模块之间相互引用的部分处理好,使的各个模块之间能够正确的衔接。链接器的工作就是把一些指令对其他符号地址的引用加以修正。链接过程主要包括了地址和空间分配、符号决议和重定位等这些步骤。

目标文件

每个模块的源代码文件经过编译器编译成目标文件,目标文件和库一起链接形成最终可执行文件

你可能感兴趣的:(编译)