1.编译链接
1.1编译链接过程
1.2编译链接各阶段的任务
预编译---->.i
- 将所有的”#define”删除,并展开所有的宏定义;
- 处理所有条件预编译指令,比如”#if” “#endif” “elif” “else” “#endif”;
- 处理“#include“预编译指令,将被包含的文件插入到该预编译指令的位置 ;
- 删除所有的注释;
- 添加行号和文件标识名,以便于编译时编译器产生调试用的行号信息以及用于编译时产生编译错误或者警告时能够显示行号;
- 保留所有的#pragma编译器指令,因为编译器必须要使用他们。
- 在预编译后的.i文件不含有任何的宏因为所有的宏已经被展开,包含的头文件也已经插入到.i文件中。所以当我们无法判断宏定义是否正确或头文件包含是否正确时,可以查看预编译后的文件来确定
编译---->.s
- 扫描、词法分析;
- 语法分析: 一条表达式中的分析;
- 语义分析:结合上下文进行分析;
- 源代码优化:源代码优化在语法树上优化比较困难,所以将语法树转化为中间代码。中间代码将编译分为前后端,之前都是编译器前端,之后都是编译器后端;
- 生成汇编指令。
汇编---->.o
- 将汇编代码转变为机器可以执行的二进制指令(生成.o文件)
- 将汇编程序翻译成可重定位目标程序(二进制)
链接---->.exe
- 将目标文件通过经过合并段和符号表、符号解析、分配地址和空间、符号重定位;
- 更改ELF头地址,变为可执行目标文件(包括使用到的库函数中的各种.o文件的链接)。
可执行文件
windows下是.exe,Linux下是ELF
- 创建虚拟地址空间和物理内存的映射(内存映射结构体):创建页目录。页表;
- 加载指令和数据;
- 入口地址写入下一行指令寄存器。
静态库和共享库的区别参考 前面的博文:https://blog.youkuaiyun.com/qq_41431406/article/details/86493571