第 4 章 · 指令系统

指令格式、寻址方式、CISC(x86)/ RISC(ARM/RISC-V)的根本分歧——ISA 这份「软硬件合同」(第 1.2 节)怎么写。

4.1 指令格式:操作码 + 地址码

一条指令 = 操作码(opcode) + 地址码(操作数)。按操作数个数:

格式形式特点
三地址add a, b, ca = b + c,直观但指令长
二地址add a, ba = a + b,结果覆盖一个源(x86 主流)
一地址add a隐含累加器 ACC(老式机器)
零地址add隐含栈顶(JVM 字节码)

指令长度是核心权衡:定长(RISC-V/ARM 均 32 位)解码简单、利于流水线取指;变长(x86 1~15 字节)编码密度高、但解码器逐字节判边界,是取指负担。

4.2 寻址方式:操作数从哪来

操作数藏在六种地方(记 EA 为有效地址):

寻址方式指令例子EA / 操作数用途
立即add r1, #5操作数在指令里常量
寄存器add r1, r2操作数在寄存器最快,最常用
直接ld r1, 0x1000EA = 0x1000访问全局变量
寄存器间接ld r1, (r2)EA = r2指针解引用
变址ld r1, 0x100(r2)EA = r2 + 0x100数组 a[i]、结构体字段
基址+变址ld r1, (r2, r3)EA = r2 + r3二维数组
相对jmp targetEA = PC + 偏移分支跳转

对比:寻址方式几乎一一对应 C——寄存器间接=指针变址=base+offseta[i]/struct.field相对=if/goto

注意:RISC-V 只有 4 种寻址方式,x86 有十几种(含 (%rbx,%rcx,8) 基址+变址×比例)。寻址越多单条越强(CISC 一条 mov 干完取数+加+乘),但解码越复杂、越难流水化。

4.3 CISC vs RISC

根源在「复杂度放软件还是硬件」:

维度CISC(x86)RISC(ARM / RISC-V)
指令长度变长(1~15B)定长(32 位,ARM 有 16 位 Thumb)
指令数量数百上千少而精(RISC-V 基础仅 ~40 条)
寻址方式十几种3~4 种
访存add 可直接读写内存只有 load/store 访存(load-store 架构)
寄存器少(x86-64 通用 16 个)多(RISC-V 32 个)
实现复杂解码器,常微码化硬布线,易流水
代表桌面/服务器移动/嵌入式/新兴

RISC:每条指令简单、等长、单周期,复杂度交给编译器——换流水线好做、主频高、功耗低。CISC:一条指令多做点事,省指令数、省内存带宽,代价是解码难。

对比:RISC 赢移动端,CISC 守桌面/服务器。现代 x86 表面 CISC,内部把复杂指令译码成 RISC 风格**微操作(µop)**再执行;ARM/RISC-V 靠定长吃满流水线红利。故「CISC vs RISC」边界早已模糊,真正决定性能的是微架构(第 5、6 章)。

4.4 x86 vs ARM vs RISC-V

特性x86-64ARM (AArch64)RISC-V
设计者Intel/AMDArm 公司(授权)开源社区
长度变长 1~15B定长 32 位定长 32 位(可扩展 16/48)
寄存器16 通用 + 标志位31 通用 + 零寄存器32 通用 + 零寄存器 x0
条件执行标志位 + 条件跳转部分条件执行(CSEL 等)无标志位,比较+分支
授权封闭需授权费免费开源
生态桌面/服务器霸主手机/嵌入式正在扩张

注意:RISC-V 的 x0 硬连线到 0——写被丢弃、读得 0,省掉「清零指令」,且作基址让 ld a0, 0(x1) 天然变直接寻址;ARM xzr 同理。这是 RISC 用「特殊寄存器」替代「额外寻址方式」的手法。

4.5 与后续各章对照

  • 第 5 章:opcode、寄存器号、立即数如何从 IR 译码成控制信号——本章是合同文本,第 5 章是执行合同的机器。
  • 第 6 章:定长 vs 变长直接决定取指难度;RISC 的 load-store 让数据冒险更规整、易转发。
  • 第 10 章:寻址方式、寄存器约定落到 x86-64 汇编即 mov rax, [rbx+8]lea rax, [rbx+rcx*4]