Add files via upload

This commit is contained in:
雾島风起時
2025-09-25 04:02:19 +08:00
committed by GitHub
parent 6d955ffc2a
commit 49832f115f
25 changed files with 1001 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
### 解释程序的编译和链接,编译的过程中会有哪些操作
**编译:从源代码到目标代码**
**编译(Compilation** 是一个多阶段的过程,它将我们用高级语言(如 C、C++)编写的源代码,转换成机器能理解的低级代码。这个过程通常由编译器(如 GCC, Clang)完成,可以细分为以下几个阶段:
**1. 预处理 (Preprocessing)**
**预处理器**是编译过程的第一个阶段。它的主要工作是处理源代码中的预处理指令,这些指令以 `#` 开头
- **头文件包含**`#include <stdio.h>` 指令会将 `stdio.h` 文件的内容完整地复制到当前文件中
- **宏展开**`#define PI 3.14159` 会将所有出现的 `PI` 替换为 `3.14159`
- **条件编译**`#ifdef DEBUG``#endif` 这类指令会根据特定条件决定是否编译某段代码
预处理阶段完成后,会生成一个**`.i` 文件**,它是一个纯文本文件,包含了所有展开后的代码,没有任何 `#` 指令
**2. 编译 (Compiling)**
在这个阶段,**编译器**开始真正的工作。它会检查预处理后的 `.i` 文件,进行语法分析和语义分析,并将其转换成**汇编代码**
- **语法分析**:检查代码是否符合语言的语法规则,比如括号是否匹配,分号是否遗漏
- **语义分析**:理解代码的含义,比如变量是否已声明,类型是否匹配
- **中间代码生成**:生成一种与特定机器无关的中间代码
- **代码优化**:对中间代码进行各种优化,例如删除不必要的代码、简化表达式等,以提高程序运行效率
这个阶段会生成一个**`.s` 文件**,里面全是人类可读的汇编语言指令
**3. 汇编 (Assembling)**
**汇编器**负责将汇编代码 `.s` 文件转换成机器码
- 它将每条汇编指令翻译成对应的二进制机器指令
- 同时,它会处理程序中使用的各种符号(比如函数名和全局变量名),并在一个**符号表**中记录下它们的位置
汇编完成后,会生成一个**`.o` 文件**,也称为**目标文件**(Object File)。这个文件是二进制格式,但它还不是一个可执行文件,因为它可能依赖于其他文件中的函数或数据
**链接:将目标文件组装成可执行文件**
**链接(Linking** 是编译过程的最后一个阶段。**链接器**(Linker)的工作是把一个或多个**目标文件**以及需要的**库文件**Library Files)组合在一起,创建出一个完整的可执行文件
链接过程主要解决两个问题:
1. **符号解析(Symbol Resolution**:当你在一个目标文件中调用另一个目标文件中的函数时,比如 `main.o` 调用了 `printf` 函数,编译器在 `main.o` 中只知道 `printf` 的名字,但不知道它在哪里。链接器会找到 `printf` 所在的库文件(比如 `libc.a`),并用 `printf` 函数的实际内存地址来替换 `main.o` 中对它的引用
2. **地址重定位(Address Relocation**:目标文件中的代码和数据地址都是相对于文件开头的。链接器会将它们重新分配到最终可执行文件的内存地址空间中,确保每个函数和变量都有一个唯一的、确定的地址
链接完成后,我们最终得到一个完整的、可以直接运行的**可执行文件**