编译和链接
编译过程
预编译
生成.i 文件 不包含任何宏定义,宏被展开
编译
汇编
链接
编译器做了什么
词法分析
有限状态机算法可以将源代码的字符序列分割成一系列的记号。
array[index] = (index + 4) * (2 + 6)
image
词法分析一般包括:关键词、标识符、字面量(包含数字、字符串)和特殊符号(加号、等号)
语法分析
对词法分析的记号进行语法分析,产生语法树,树的节点是表达式。语法层面的分析,并不了解这个语句是否真正有意义。
assignExpression
SubscriptExpression[] MultipicativeExpression *
Identifier Identifier Additive Additive
Expression Expression Expression(+) Expression(+)
array index
Identifier Number Number Number
Index 4 2 6
语义分析
语法分析仅仅是完成了对表达式的语法层面的分析,但是它并不了解这个语句是否真正有意义
静态语义
编译期可以确定的语义,包括声明和类型的匹配,类型的转换。比如当一个浮点型的表达式赋给一个整形的表达式时,其中隐含了一个浮点型到整形的转换的过程,语义分析过程中需要完成这个步骤,
动态语义
运行期可以确定的语义,程序运行期出现的语义相关的问题。
经过语义分析阶段以后,整个语法树的表达式都被标识了类型,如果有些类型需要做隐式转换,语义分析程序会在语法树中插入相应的转换节点,
中间语言生成
在源代码级别有一个优化过程,源代码优化器会在源代码级别进行优化,(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)
模块拼装 - 静态链接
人们把每个源代码模块独立编译,然后按照需要将他们“组装”起来,这个组装模块的过程就是链接,链接的主要内容就是吧各个模块之间相互引用的部分处理好,使的各个模块之间能够正确的衔接。链接器的工作就是把一些指令对其他符号地址的引用加以修正。链接过程主要包括了地址和空间分配、符号决议和重定位等这些步骤。
目标文件
每个模块的源代码文件经过编译器编译成目标文件,目标文件和库一起链接形成最终可执行文件
网友评论