16 位程序集:无法取消引用某些寄存器

16-bit Assembly: cannot deref some registers

我正在尝试以下 Intel 16 位指令:

mov si, word [reg]

其中 reg 是一些寄存器。如果 regbx,它可以正常编译,但当它是 axcxdx 时,它就不能编译。我正在使用 NASM 作为我的汇编器。我确信这是由于指令集中的一些限制。有人可以解释一下限制及其背后的理由吗?

16位寻址模式只能使用以下变址寄存器:

bx
si
di
bp
bx + si
bx + di
bp + si
bp + di

同样,SIB 寻址不适用于 16 位寻址模式。

如果你想使用其他索引寄存器,你总是可以使用32位寻址方式,例如[eax]。只要您 运行 您的代码在 80386 或更新的处理器上,这就有效。

存在此限制是因为 modr/m 字节只有三位用于(索引)寄存器。正如您在上面所看到的,恰好存在 8 种可能的变址寄存器组合。我不知道他们为什么将寻址模式设计成那样,但对于像 8086 这样的 70 年代 16 位处理器来说,这听起来很合理。

在 32 位模式和长模式下,此方案已更改,因此 8 个可能的索引寄存器中有 7 个引用 eax、ebx、ecx、edx、esi、edi 和 ebp,而引用 esp 的内容则表示同胞字节的存在允许众所周知的 [base+index*scale] 寻址模式。