跳转到内容

指令集架构

指令集架构(ISA)定义寄存器、指令、寻址方式与内存模型,是编译器与 CPU 之间的稳定接口。微架构每两年换一代,ISA 却稳定几十年——接口与实现分离(→ 从晶体管到应用:抽象层次)在体系结构里最纯粹的一次体现。本章比较 RISC 与 CISC 的设计哲学、三大 ISA 的现状,以及调用约定与栈帧布局。

一份 ISA 规范回答以下问题:

  • 状态:有哪些寄存器(通用、浮点/SIMD、特殊如 PC 与 flags)、多大、怎么编号;
  • 指令:每条指令对状态做什么(算术、访存、控制流、系统);
  • 寻址方式:指令如何计算访存地址(基址+偏移、缩放索引等);
  • 内存模型:并发访问内存时各核看到什么顺序(弱序/TSO),这直接决定无锁编程的可行性(→ 并发与同步);
  • 异常与特权级:非法行为如何上报,用户态与内核态如何切换(→ 进程、线程与上下文切换)。

ISA 是语义契约而非实现说明书:"这条指令做什么"是契约,"如何在一个周期内做完"是微架构的自由。

RISC(精简指令集)CISC(复杂指令集)
指令少而规整、定长编码多而复杂、变长编码
访存只有 load/store 触碰内存许多指令可直接访存
设计哲学让编译器做优化让硬件一条指令干更多事

历史给这个争论的裁决很有趣:指令集与实现方式可以解耦。x86 在前端把复杂指令翻译成类 RISC 微操作(μops),后端实际执行的是 RISC 风格的微架构。CISC 的兼容性负担保留在接口上,RISC 的规整性保留在实现里——两边都对了。

  • x86-64:桌面与服务器的事实标准。优势是四十年生态与兼容性;代价是变长编码复杂、功耗优化空间受限。
  • ARM(AArch64):移动端统治,服务器份额快速增长(AWS Graviton、Apple Silicon)。定长编码对取指与解码友好。
  • RISC-V:开源、免许可费,模块化——基础指令集(RV32I/RV64I)加可选扩展(M 乘除、A 原子操作、F/D 浮点、V 向量),芯片可以只实现需要的部分。学术与嵌入式先行,正在进入服务器。

ISA 之外,**调用约定(calling convention)**约定函数之间如何协作,通常由 ABI 固定:

  • 传参:前几个参数放寄存器(x86-64 System V 用 rdi, rsi, rdx, rcx, r8, r9),放不下的压栈;
  • 返回值:约定寄存器(如 rax);
  • 寄存器保存责任:**调用者保存(caller-saved)**寄存器跨调用可能被破坏,**被调用者保存(callee-saved)**寄存器若要使用必须先备份——这个划分直接决定编译器生成代码的保存/恢复指令。

**栈帧(stack frame)**是函数在运行栈上的私有区域:帧指针与栈指针之间,存放局部变量、被调用者保存的备份、返回地址。函数的进入与退出就是一串固定的栈帧操作(prologue/epilogue)。理解栈帧才能理解:递归的内存成本、缓冲区溢出为何能覆盖返回地址(→ 内存安全与常见漏洞)、以及调试器的回溯如何工作。

  • ISA 是硬件与软件的语义契约:状态、指令、寻址、内存模型、异常与特权级
  • RISC/CISC 之争的裁决是解耦:x86 前端翻译成 μops,后端是 RISC 风格实现
  • RISC-V 的模块化与开放许可改变 ISA 经济学
  • 调用约定约定传参与寄存器保存责任;栈帧是理解递归、溢出漏洞与调试回溯的钥匙