16位汇编:无法解析某些寄存器

Fre*_*ool -1 assembly x86-16

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

mov si, word [reg]

在哪里reg注册.如果regbx,它编译好,但是当它是ax,cx或者dx.我正在使用NASM作为我的汇编程序.我确定这是由于指令集中的一些限制.有人可以解释其背后的限制和理由吗?

fuz*_*fuz 6

只有以下索引寄存器可用于16位寻址模式:

bx
si
di
bp
bx + si
bx + di
bp + si
bp + di
Run Code Online (Sandbox Code Playgroud)

同样,16位寻址模式不支持SIB寻址.

如果要使用其他索引寄存器,可以始终使用32位寻址模式,例如[eax].只要您在80386或更新的处理器上运行代码,这就可以工作.

存在这种限制是因为modr/m字节对于(索引)寄存器只有三位.如您所见,正好存在8种可能的索引寄存器组合.我不知道为什么他们设计的寻址模式是这样的,但对于80年代的16位处理器来说听起来很合理,因为它是8086.

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

  • 这些选择必须包括8080寻址模式,以使asm源的机器转换成为可能([为什么前四个x86 GPR以这种不直观的顺序命名?](https://retrocomputing.stackexchange.com/q/5121)).所以BX = HL必须是一个可能的基础.source/dest索引可能是新的. (2认同)
  • @PeterCordes 8080 还支持现在的“cx”和“dx”作为基址寄存器,所以我不太明白这一点。汇编翻译器使用 `mov %cx, %si 来实现这些;mov (%si)、%al` 或类似的。 (2认同)