为什么 lw 指令的第二个参数同时包含偏移量和 regSource?

Why does the lw instruction's second argument take in both an offset and regSource?

所以lw指令的格式如下:lw RegDest, Offset(RegSource)。为什么第二个参数同时接受偏移量和寄存器源?为什么不只有一个(即只注册源)?

因为您还打算用剩下的 32 位指令字做什么? (假设您是 CPU 设计 MIPS 指令集的架构师)。

它让 LUI + LW 在 2 条指令中从任意 32 位地址加载,而不是 3。对于循环展开或结构指针->成员访问,避免指针数学的 ADDIU 指令。即 在 LW/SW 上花费 space 的编码量可以使 MIPS 程序更高效。 有时您只需要 0($reg),但其他时候它会计算寄存器中的最终地址是浪费指令。

省略16位立即数位移并不能使指令更短。 MIPS 是具有固定长度指令字的 RISC。 (它可能是 R 型而不是 I 型,但你仍然会有那种格式的未使用位。经典 MIPS 有很多未使用的编码 space,并且在 [=63] 上花费编码 space =], LB/LBU/SB, 等等, 是值得的。)

MIPS 没有很多不同的操作码(尤其是没有任何 FPU 指令和 64 位指令的经典 MIPS)。它使用了大量的指令编码space来支持大多数指令的立即数形式,立即数很大。 (例如,与 ARM32 不同,ARM32 在每条指令中使用 4 位用于预测执行,而更多位用于 "flexible" 源操作数(可选地旋转或移位常量或另一个寄存器,或立即数常量)。但是 ARM 立即数被编码作为 8 位旋转,允许许多在现实生活中常见的有用位模式。)


MIPS 只有一种寻址模式,与 (reg).[ 相比,imm16(reg) 可以节省大量 addiu 条指令。 =23=]

例如,考虑加载或存储到静态(或全局)变量的 C 函数。喜欢

unsigned rng(void) {
    static unsigned seed = 1234;
    return (seed = seed * 5678 + 0x1234);
}

编译器生成的(或手写的)asm 需要从 seed 加载和存储,所以你需要它在寄存器中。但它是一个 32 位常量,不适合单条指令。在手写的 asm 中,您可能会使用像 la $t0, rng.seed 这样的伪指令,它将 assemble 转换为 lui $t0, hi(rng.seed) / ori $t0, $t0, lo(rng.seed)。 (hi 和 lo 得到 32 位地址的一半)。

但你可以做得更好:

lui   $t0, hi(rng.seed)
lw    $t1, lo(rng.seed) ($t0)

即使用地址的低16位作为加载指令中的16位位移。这实际上就是 compilers like gcc do:

rng:    # gcc5.4 -O3
    lui     ,%hi(seed.1482)
    lw      ,%lo(seed.1482)()
    nop                       ; classic MIPS has a 1-cycle "shadow" for loads before the result is usable, with no pipeline interlock
    sll     ,,5          ; I should have picked a simpler multiply constant (with fewer bits set)
    sll     ,,3
    subu    ,,
    sll     ,,3
    subu    ,,
    subu    ,,
    sll     ,,4
    addu    ,,
    sll     ,,1
    addiu   ,,4660
    j       
    sw      ,%lo(seed.1482)()       ; branch-delay slot

seed.1482:
    .word   1234

寄存器的小立即位移还有很多其他用途。例如:

  • 如果编译器溢出任何内容,则访问堆栈上的局部变量
  • struct 字段
  • 展开循环中的数组访问。 (MIPS 有 32 个整数寄存器,几乎是为软件流水线设计的,以展开循环)。
  • 小型编译时常量数组索引。

如我所说,对于那些非常适合 MIPS 的额外 16 位指令字,您无能为力。您可以保留少于 16 位的位移,但 MIPS 不是 PowerPC(那里有很多很多操作码)。