为什么要进行编译链接?
1、人们通常写的都是高级语言,对于计算机来说,只认识二进制的机器指令,不认识高级语言,所以要通过编译将高级语言转换为计算机可识别的低级语言
2、编译链接是在磁盘上,运行时要加载到内存中
hello.c
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
在linux下,当我们使用GCC来编译Hello World程序时,只须使用简单的命令gcc hello.c,那么这背后完成了那些过程呢?下面我们来看看一个代码要运行起来需要完成的4个步骤,并且这4步都干了什么事?
1、预编译 .i
预编译的过程相当于如下指令
gcc -E hello.c -o hello.i
预编译过程主要处理那些源代码文件中的以”#“开始的预编译指令,主要规则如下:
1> 将所有的”#define“删除,并且展开所有的宏定义。
2> 处理所有条件预编译指令,比如”#if“、”#ifdef“、”#elif“、”#else“、”#endif“。
3> 处理”#include“预编译指令,将被包含的文件插入到该预编译指令的位置。
4> 删除所有的注释”//“和”/**/“。
5> 添加行号和文件名标识,以便在编译时编辑器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号。
6> 保留所有的#pragma编译器指令,因为编译器需要使用它们。
2、编译 .s
编译的过程相当于如下指令
gcc -S hello.i -o hello.s
编译过程就是把预处理完的文件进行如下操作:
1> 词法分析
2> 语法分析
3> 语义分析
4> 代码优化
最后生成相应汇编代码文件,这个过程往往是整个程序构建的核心部分,也是最复杂的部分之一。
3、汇编 .o
汇编的过程相当于如下指令
gcc -c hello.s -o hello.o
汇编器将汇编代码转变成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令,所以汇编器的汇编过程相对于编译器来讲比较简单,它没有复杂的语法,也没有语义,也不需要做指令优化,只是根据汇编指令和机器指令的对照表一一翻译即可。
4、链接 .exe
链接过程进行如下操作:
1> 合并段和符号表
2> 符号解析
3> 分配地址空间
4> 符号的重定位
最后在进行运行
1> 创建虚拟地址空间和物理地址内存的映射(创建映射结构体)
2> 加载指令和数据
3> 将入口地址写入下一行指令寄存器
编译链接原理
最新推荐文章于 2022-03-15 11:16:25 发布