Chapter 0 课程导论
0.1 这门课研究什么
计算机系统通过不同抽象层组织复杂性。高级语言描述算法,编译器把它翻译成机器指令,处理器再通过寄存器、运算单元与控制逻辑执行这些指令。汇编语言位于软件与硬件的交界处,是理解“程序究竟怎样运行”的重要入口。(课件第 5 页)
flowchart TB
A[算法与应用] --> B[高级语言与操作系统]
B --> C[指令集体系结构 ISA]
C --> D[微体系结构:流水线、乱序执行]
D --> E[寄存器、数据通路、控制单元]
E --> F[逻辑门与晶体管]
指令集体系结构(Instruction Set Architecture, ISA)规定软件可见的指令、寄存器和执行语义。微体系结构(Microarchitecture)则决定一颗具体处理器如何实现这些语义,例如怎样安排流水线、缓存和执行单元。同一 ISA 可以有许多不同实现。
课程的两条主线是:
- 汇编程序设计:数据如何表示,操作数放在哪里,指令怎样改变寄存器、内存和控制流。
- 微机接口:处理器如何通过接口与外设交换数据,如何借助中断和定时器协调工作。
接口(Interface)或端口(Port)是计算机与外设之间的连接点。课件第 10–12 页区分了串行、并行通信,以及中断控制器、定时器承担的控制功能。这里的物理连接口与后续指令中的 I/O 端口地址相关,但不是同一层次的概念。
0.2 为什么学习汇编
0.2.1 理解程序的实际行为
操作系统、固件(Firmware)、设备驱动、嵌入式系统、编译器和密码学实现都可能直接涉及汇编。即便日常开发不手写汇编,阅读编译结果仍能帮助定位性能问题和理解语言规则。(第 6–9 页)
课件使用下面的例子说明源代码与机器指令之间的关系:
int silly(int a) {
return (a + 1) > a;
}
若 a 取 INT_MAX,a + 1 超出 int 的可表示范围。在 C/C++ 中,这是未定义行为(Undefined Behavior, UB)。在没有溢出的合法执行中,表达式恒为真,编译器因而可能把函数优化成直接返回 1。
课件展示了某次 Clang 编译中 -O0 保留加法、比较,而 -O1 直接返回 1 的结果。它说明编译器会利用语言语义做优化,不能把这次低优化级别下的回绕结果当作语言保证。课件第 7 页的 “unspecified behavior” 应更正为 “undefined behavior”;Clang 的检查器也将有符号溢出列为 UB 检查项。参见 Clang UndefinedBehaviorSanitizer 文档。
0.2.2 理解优化改变了什么
另一个例子是求和:
int Sum1ToN(int n) {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += i;
}
return sum;
}
虽然函数名写作 Sum1ToN,循环实际累加的是 \(0\) 到 \(n-1\)。在 \(n>0\) 且讨论的算术没有溢出时:
编译器可能保留循环、展开循环、使用向量指令,或识别这种求和模式并生成闭式计算。具体结果依赖编译器、版本、优化参数和目标平台。n<=0 时原程序返回 0,不能无条件套用公式;直接在 C 中写 n*(n-1)/2 还可能因为中间乘法而提前溢出。(第 8 页)
有效的观察方法是固定源代码,只改变一个因素,比较指令数量、循环结构、访存与寄存器使用。看见更短的汇编也不能直接断言运行更快,还需要测量。
0.2.3 理解局部性能优化
课件以 PTX(Parallel Thread Execution)、ARM NEON 以及移动端推理框架为例,说明高性能实现有时需要控制向量化、通信和硬件资源使用。(第 9 页)
这里的学习重点是:先定位热点,再理解瓶颈,最后判断手工优化是否有收益。课件中的具体项目是教学案例,不表示所有应用都需要手写汇编。
0.3 课程内容与学习顺序
第 13 页列出的章节安排如下;本目录现有课件覆盖导论与第 1–3 章。
| 主题 | 教材章节 | 要解决的问题 |
|---|---|---|
| 微处理器与体系结构 | 1–2 | 数据怎样表示,寄存器和内存怎样组织 |
| 寻址方式 | 3 | 指令怎样找到操作数 |
| 数据传送指令 | 4 | 怎样复制数据、使用栈和字符串操作 |
| 算术与逻辑指令 | 5 | 怎样运算并解释标志位 |
| 程序控制指令 | 6 | 怎样实现分支、循环和过程调用 |
| 汇编与 C/C++ 混合编程 | 7 | 不同语言怎样共享调用约定 |
| 基本 I/O 接口 | 11 | 怎样与外设通信 |
| 中断 | 12 | 怎样响应异步事件 |
| 算术协处理器与 SIMD | 14 及补充 | 怎样处理浮点数和并行数据 |
建议先掌握数据位宽、补码和小端序,再学习寄存器与地址转换,最后把寻址公式对应到数组、结构体和栈帧。否则容易把“操作数的值”“保存值的地址”和“地址所属的内存空间”混在一起。
0.4 教材、参考资料与工具
课件第 2–4 页的主要教材是 Barry B. Brey 的 The Intel Microprocessors 第 8 版。其他参考书包括白洪欢《80X86 汇编语言程序设计基础》、Irvine 的 x86 汇编教材,以及 Kusswurm、Jo Van Hoey 的 x86/x64 汇编教材。
学习时可以把资料分成三类:
| 资料或工具 | 用途 |
|---|---|
| 教材和本课程课件 | 建立概念、完成章节习题 |
| Intel/AMD 架构手册 | 核对指令语义、编码和模式限制 |
| MASM 参考手册 | 核对伪指令、运算符和汇编器语法 |
| Compiler Explorer | 对照 C/C++ 源码与编译生成的汇编 |
| 8086 模拟器、汇编器与反汇编器 | 单步观察寄存器、内存、标志位及机器码 |
架构手册入口见 Intel 官方手册索引。使用工具时应记录目标是 16 位、32 位还是 64 位模式,以及汇编器采用 Intel 还是 AT&T 语法,这些设置直接影响代码含义。
0.5 实验与探索性研究
0.5.1 基础实验
课件第 14 页将环境搭建、分支、循环、汇编与 C/C++ 混合编程、x64 编程和 I/O 接口列为可选预备实验。这些练习适合用来确认自己能读懂机器状态变化。
0.5.2 Project 1:从高级抽象到汇编
项目要求研究一种高级语言抽象在汇编层面如何体现。(第 15–18 页)
抽象泄漏(Leaky Abstraction)的含义是:抽象虽然隐藏实现细节,但在性能、异常行为或资源限制等场景中,底层机制仍可能影响使用者。汇编能帮助找到这种影响来自哪里。
课件给出的选题包括函数调用与栈帧、虚函数与动态分派、异常处理、栈保护、Lambda 与闭包、泛型与模板、智能指针、递归与迭代,以及整数溢出与 UB。
可以按以下步骤组织研究:
- 缩小问题:例如“开启优化后,一个捕获整数的 Lambda 是否仍需要独立栈对象”。
- 提出假设:说明预期会出现哪些存储、加载或调用指令。
- 设计对照:保持平台、编译器版本和代码输入一致,只改变捕获方式或优化级别。
- 收集证据:保存源代码、编译选项、关键汇编片段和必要的性能数据。
- 解释与评价:区分语言保证、应用二进制接口(Application Binary Interface, ABI)约定和某次编译的实现选择。
课件要求独立完成并提交报告。以上步骤是对研究方法的整理,不是新增作业要求。
0.5.3 Project 2 与往年研究案例
当前课件把“评估大语言模型的代码反编译能力”列为暂定方向。第 20–22 页则明确标作往年 Project 2,介绍排序算法发现、二进制函数命名、编译优化和二进制代码摘要等研究。
可研究的问题包括:模型能否识别函数功能,等价指令改写是否影响回答,混淆是否影响理解,以及能否判断两个函数功能相同。评价时应使用可验证的功能结果,不能只凭解释文字是否流畅。
0.6 课件中的考核安排
以下仅记录所提供课件第 18–19 页的安排,具体实施以课程后续通知为准。
| 项目 | 课件记录 |
|---|---|
| 探索性研究 | 总评占比 30% |
| 期末考试 | 总评占比 70% |
| 期末考试成绩要求 | 至少 50 分 |
| Project 1 截止日期 | 11 月 10 日 |
| Project 2 截止日期 | 12 月 31 日 |
课件没有在这些日期旁单独标注年份。课程群、入群口令等联络信息请查课程原始通知。
0.7 术语表
| 中文术语 | English | 缩写 | 含义 |
|---|---|---|---|
| 汇编语言 | Assembly Language | — | 用助记符和操作数表达机器指令 |
| 指令集体系结构 | Instruction Set Architecture | ISA | 软件可见的机器接口与执行语义 |
| 微体系结构 | Microarchitecture | — | 具体处理器实现 ISA 的组织方式 |
| 固件 | Firmware | — | 面向设备初始化和底层控制的软件 |
| 未定义行为 | Undefined Behavior | UB | 语言规范不对该执行的结果施加要求 |
| 应用二进制接口 | Application Binary Interface | ABI | 参数传递、寄存器使用、数据布局等二进制约定 |
| 抽象泄漏 | Leaky Abstraction | — | 底层机制透过抽象影响上层行为 |
| 反编译 | Decompilation | — | 从低层代码恢复较高层程序表示 |