大学本科教育中有两门课可能涉及汇编语言的讲解,一门是《微机原理与接口技术》,一门是《计算机组成原理与汇编》,但它们讲解的往往是16位或32位指令集架构,分别以 Intel 8086 芯片和 80386 芯片为代表。随着64位系统的广泛应用,目前的主流架构转向了 x86_64,同时基于 Linux 系统的汇编环境与微软的汇编环境也不完全相同,因此有必要在大学课程基础上做一定扩展。
参考书籍:汇编程序设计与计算机体系结构:软件工程师教程
xx位 指的是 CPU 的通用寄存器(General Purpose Register)的数据宽度为 xx 位比特。
Note: 尽管当前的 x86_64 处理器是64位的,但只用到了低48位,因此理论上可以寻址 264 比特的地址空间,实际上只支持 248 比特。
| 64位 | 32位 | 64位 | 32位 | ||
|---|---|---|---|---|---|
| 通用寄存器 | RAX | EAX | 段寄存器 | / | CS |
| RBX | EBX | / | DS | ||
| RCX | ECX | / | ES | ||
| RDX | EDX | / | SS | ||
| RSI | ESI | / | FS | ||
| RDI | EDI | / | GS | ||
| RBP | EBP | 指令指针寄存器 | RIP | EIP | |
| RSP | ESP | 标志寄存器 | RFLAGS | EFLAGS | |
| R8~R15 | / | / | / |
由上表可以看出共有四类寄存器:通用寄存器(64位有16个,32位有8个),段寄存器(64位没有段寄存器),指令指针寄存器和标志寄存器。汇编程序操作的一般都是通用寄存器。从16位发展到32位,再到64位,各个体系都做到向前兼容。因此在64位架构下,依然可以操作如 EAX 这样的32位寄存器,它对应的是 RAX 寄存器的低32位。当使用小位数寄存器的名义操作大位数寄存器时,实际上操作的是大位数寄存器中与小位数相对应那部分寄存器。
例如,以 AX 的名义操作 EAX,实际上操作的就是 EAX 的低16位,因此会破坏原本 EAX 中的部分数据。

rflags 中可用的只有低32位,因此 x86 与 x86_64 共用一套状态标志。
LAHF = Load AH Flags, SAHF = Save AH Flags
由英文含义可以知道,LAHF 是向 AH 寄存器(AH 是 AX 寄存器的高8位)中加载状态标志位;SAHF 是保存 AH 寄存器中的内容到状态标志位。但我们由前面的介绍知道,rflags/eflags 是32位寄存器,而 AH 寄存器只有8位,那么是哪些标志位可以传给 AH (或通过 AH 加载)呢?关注的8个标志位如下(实际上就是状态寄存器的低8位)
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|
| SF(符号标志位) | ZF(零标志位) | U 恒为0 | AF(辅助进位标志位) | U 恒为0 | PF(奇偶校验标志位) | U 恒为1 | CF(进位标志位) |
表格中的 U 表示 Unused,即这些位用不到(也可以理解为暂时保留),第1位应始终为1,第3、5位应始终为0。
BCD 码指用 4 位二进制数表达 1 位十进制数的编码方式。如 0b 0110 = 0d 6。
CPU,中央处理单元,是计算机的核心,能够处理广泛类型的工作。除 CPU 外的 XPU 都可以理解为针对特定任务的加速处理单元。
GPU,图形处理单元,专注于处理 3D 渲染、视觉效果真实性等图形处理任务;TPU (Tensor Processing Unit) ,张量处理单元,用于神经网络张量计算的加速任务;FPU (Floating-Point Unit) ,浮点运算单元,它通常整合在 CPU 中,专注于浮点运算任务;NPU (Neural-network Processing Unit) ,神经网络处理单元,采用“数据驱动并行计算”的架构,擅长处理视频、图像类的海量数据。
目前有三种较为流行的汇编器
GAS (GNU Assembler) 是一款基于 Linux 的汇编器,主要供 GNU 项目使用,用于对 Linux 内核及其他软件进行进行汇编。
MASM (Microsoft Macro Assembler) 是微软操作系统的专属汇编器,于 1981 年随 Visual Studio 一起发布。
NASM (Netwide Assembler) 的设计初衷是当时没有一个免费且好用的x86汇编器,目前是 Linux 平台上最受欢迎的汇编工具之一。
| 汇编器 | 语法规则 | 可使用的开发环境 |
|---|---|---|
| GAS | AT&T | Apple Xcode |
| MASM | Intel | Visual Studio |
| NASM | Intel | Linux 命令行编辑工具 |
本科阶段学习的应该都是 Intel 语法,没办法,谁让 Microsoft 统治第三世界呢。AT&T 语法和 Intel 语法还是存在许多区别的,之后的语法规则都是基于 AT&T,至于 Intel 的规则,不妨翻出那本落满灰尘的教材或者找一门慕课吧。
保留字、命令(directive,国内通常称为伪指令或伪操作)、区段、标识符和指令(instruction)。