目录
程序的编译链接过程
1.编译过程中的预处理阶段
2.编译过程中的正式编译阶段
3.编译过程中的汇编阶段
4.链接过程
程序的编译链接过程
一个程序的源码文件要经过复杂的编译链接过程才能被转换为可执行的机器指令(二进制指令)
编译链接过程概述:
- 编译过程:组成一个程序的每个源码文件通过编译过程分别被转换成目标文件(linux下为.o文件)
(注意每个源文件的编译过程都是分别独立进行的)- 链接过程:每个目标文件(.o文件)由链接器(linker)链接在一起,形成一个单一而完整的可执行程序(.exe文件)
编译链接过程图:
1.编译过程中的预处理阶段
源码中的 # 修饰的语句代表预处理指令;
编译过程的预处理阶段(预处理阶段进行的是一些文本操作)主要完成的事情:
- #include所指向的头文件中的所有内容会被"复制粘贴"到#include语句所在的源文件中
- #define定义的符号的替换
- 注释的删除
注意:该阶段不进行语法检查
一个源码文件的预处理完成后会生成一个对应的 .i 源码文件
在win10的gcc编译环境下用vscode对源码文件进行预处理,在终端中输入:
gcc -E ./文件名 -o 输出的文件名(任意取)
编译器执行指令后便得到被预处理的源文件对应形成的.i文件:
2.编译过程中的正式编译阶段
编译过程的正式编译阶段主要完成的事情:
- 对文件中的源码进行语法检查以及各种分析(语法有误则报出编译错误)
- 将 .i 文件中的源代码翻译成汇编代码,生成.s文件
- 进行符号汇总
符号汇总会将.i文件中所有函数,全局变量的经过修饰的名称全部汇总起来,为符号表的生成做准备。(符号表在链接过程中起到重要作用)
在win10的gcc编译环境下用vscode对.i文件进行正式编译,在终端中输入:
gcc -S ./test.i
生成.s文件(汇编代码)
3.编译过程中的汇编阶段
编译过程的汇编阶段主要完成的事情:
- 将存储汇编指令的.s文件汇编成 .o文件(二进制文件)
- 形成符号表
符号表中存储了.s文件中所有函数的经修饰的名称(以及对应函数体的地址),全局变量的名称(以及定义它们的指令的地址);
- 注意如果当前源文件没有定义某个被调用的函数(或全局变量),那么在符号表中该函数(或全局变量)所对应的地址将为无效地址(等到链接阶段再完成寻址)
比如:
4.链接过程
链接过程主要完成的事情:
- 各.o文件的合并
- 各.o文件的符号表的合并
比如:
- 链接过程完成后如果符号表中的无效地址仍然无法得到确定,编译器就会报出链接错误
- C++中修改了C语言符号表中对函数名的修饰规则,为函数重载提供了底层机制上的支持.参见:函数重载http://t.csdn.cn/tYd4h
编译链接流程总览: