首页/计算机组成原理/指令系统/编译器汇编器链接器 🔗 在 Obsidian 中打开
计算机组成原理 · 指令系统

编译器汇编器链接器

重要度 ⭐⭐⭐⭐指令系统编译器汇编器链接器程序转换
速查
转换链:.c → 预处理 → .i → 编译 → .s → 汇编 → .o → 链接 → 可执行 → 加载 → 进程。编译器:高级→汇编;汇编器:汇编→机器码(.o);链接器:符号解析 + 重定位。

核心概念

程序转换的完整过程

源程序(.c)
  │ 预处理(cpp)
  ↓
预处理后源文件(.i)
  │ 编译器(cc1)
  ↓
汇编语言文件(.s)
  │ 汇编器(as)
  ↓
目标文件(.o)  ←── 重定位信息
  │ 链接器(ld)
  ↓
可执行文件
  │ 加载器(loader)
  ↓
内存中运行的进程

各阶段功能

  • 预处理器:处理 # 开头的预编译指令——宏替换、头文件包含、条件编译;输出 `.i` 文件(纯 C 代码)。
  • 编译器:将高级语言翻译为汇编语言;词法分析→语法分析→语义分析→代码优化→代码生成;输出 `.s` 文件;优化包括常量折叠、循环展开、死代码消除等。
  • 汇编器:将汇编语言翻译为机器语言,处理符号地址(生成符号表),生成可重定位目标文件(.o):代码段 .text、数据段 .data、符号表、重定位信息。
  • 链接器:将多个目标文件和库文件合并为可执行文件;符号解析 + 重定位;静态链接 vs 动态链接。
  • 加载器:将可执行文件从磁盘装入内存,建立进程地址空间,设置 PC 指向入口地址。

关键性质

工具输入输出核心任务
预处理器.c.i宏替换、头文件展开
编译器.i.s高级语言 → 汇编语言
汇编器.s.o汇编语言 → 机器语言
链接器.o + .a可执行符号解析 + 重定位
加载器可执行进程装入内存

符号解析与重定位

  • 符号解析:每个符号引用对应唯一定义;全局变量/函数在多个文件中只能定义一次;extern 声明只是引用,不是定义。
  • 重定位:编译时地址不确定 → 链接时确定最终地址;汇编器生成重定位条目,链接器修改地址引用。
注意「重定位」是链接器做的,不是汇编器!汇编器只负责生成重定位信息。

常见考法

考法解题套路
程序转换顺序预处理 → 编译 → 汇编 → 链接
各阶段的功能区分编译器:高级→汇编;汇编器:汇编→机器码
链接器的功能符号解析 + 重定位
静态链接 vs 动态链接静态:代码复制进可执行;动态:运行时加载共享库
编译错误 vs 链接错误编译:语法错误;链接:符号未定义/重复定义

易错点

必记
  • 编译器输出汇编语言,不是机器语言(汇编器才输出机器语言)。
  • 链接器处理的是目标文件 .o,不是源文件 .c。
  • 重定位是链接器做的,不是汇编器做的。
  • 预处理不是编译的一部分,是编译前的文本处理。
  • 外部变量声明(extern)不分配空间,定义才分配。

核心结论

  1. 程序转换:预处理 → 编译 → 汇编 → 链接 → 加载。
  2. 编译器:高级语言 → 汇编语言(含优化)。
  3. 汇编器:汇编语言 → 机器语言(可重定位目标文件)。
  4. 链接器:符号解析 + 重定位 → 可执行文件。
  5. 加载器:将可执行文件装入内存运行。

记忆卡片

编译器的输入和输出?
输入高级语言(.i),输出汇编语言(.s)。
汇编器的输入和输出?
输入汇编语言(.s),输出机器语言(.o 目标文件)。
链接器做什么?
符号解析(找定义)+ 重定位(确定地址)。
预处理器处理什么?
宏替换、头文件展开、条件编译;完整顺序:预处理→编译→汇编→链接→加载。

交互动画 · 程序转换流水线

源程序.c 预处理cpp → .i 编译cc1 → .s 汇编as → .o 链接ld → 可执行 加载loader → 进程 预处理 → 编译 → 汇编 → 链接 → 加载,最终变成内存中的进程
点击阶段按钮,观察每一步的输入与输出文件
提示:点「一键运行」依次点亮整条流水线

相关知识点

instruction-set-design instruction-format

↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。