从代码到可执行文件过程

132 阅读2分钟

「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」。

例子

一个简单的C语言程序

#include <stdio.h>
int main(){
printf("Hello World\n");
return 0;
}

到转变成操作系统真正能运行的程序的过程中经过了4个步骤,这4个步骤分别是预处理,编译,汇编,链接。

预编译过程(gcc指令)

预编译过程主要处理的是以“#”开头的预编译指令,比如说"#include","#define"等,其中的主要规则包括

  • 将"#include"包含的文件进行宏展开。
  • 处理预编译指令"#if"等
  • 删除注释
  • 添加行号和文件名标识
  • 保留编译器指令

编译过程(gcc指令)

编译过程是一个复杂的过程,它会将预处理完的文件进行词法分析,语法分析,语义分析,以及目标代码的优化。最后得到汇编代码文件。

注:编译过程的学习会在编译原理这门课中具体学习

汇编过程(as指令或gcc指令)

汇编过程是将每一条汇编指令对应到每一条机器指令。

链接

为什么会有链接过程呢?其实很好理解,当我们编译一个文件时,如果这个文件中的某条指令的某个变量(全局变量)在另外一个文件当中,这时就没有办法知道这个变量的地址(因为这个变量的地址是在编译另一个文件时分配的),这是其一,其二也有可能知道了该变量的地址但是另一个文件进行了修改,这样的话在重新编译过程时原来的地址就是错误的地址了。
基于上述原因,引入了链接这个过程。 引入链接过程后,在编译目标文件时如果无法确定变量的地址,会将这个目标地址设置为0,等到链接这个变量所在的文件时再将这个地址进行修改。