是否可以在同一条指令中使用同一个寄存器作为内存指针和数据?

Is it possible to use the same register as a memory pointer and data in the same instruction?

例如,在下面的指令中:

MOV [BX], BH

寄存器 BH 是寄存器 BX 的一部分。

这没有问题,甚至没有任何理由认为它可能会被禁止。 (除了你的教科书,显然 )。存储只是读取地址寄存器和数据寄存器,然后写入该地址的内存。
在现代 CPU 中读取寄存器通常是通过多端口寄存器文件完成的,这些寄存器文件允许在同一时钟周期内完成两个或多个独立读取。寄存器文件由 SRAM 构建而成,因此同时读取同一组单元格两次是零问题。

mov bx, bh 当然不合法,因为寄存器的宽度不同,而不是因为一个重叠。 mov cx, bh 同样是非法的。 (但 386 movzx ebx,bh 没问题。)

事实上,链表读取循环通常包含 mov bx, [bx] 之类的指令或与其他寄存器等效的指令。 (遍历链表称为“指针追逐”。)用一些数据简单地替换不再需要的指针也很常见。

存储(部分)指向指向位置的指针不太常见,但 CPU 不关心它是否有用。


有一些 ISA 的一些指令对使用相同的寄存器有限制,例如当乘法使用相同的寄存器作为输出作为输入时,较旧的 ARM 会出现问题。但是像加载或存储这样的简单指令并不奇怪。

除了更新指针寄存器以及加载到不同寄存器的寻址模式。 Nate 建议 LDR X0, [X0], 8 作为不允许的示例。 ldr x1, [x0], 8x1 = mem[x0] ; x0+=8 (post-indexed),并且不允许 x1 = x0.

x86 没有任何 pre/post-indexed 显式寻址模式,但 x86 确实有 push/pop 隐式使用 [E/R]SP 作为地址并采用一个显式数据操作数。手册准确记录了 push sp and pop sp 发生的情况。 (pop sp = mov sp, [sp],如果它是可编码的。)

一般来说,如果为该指令明确记录,您可以假设相同的寄存器(或重叠的部分寄存器)is/are 操作数 and/or 地址的有效选择。

在 x86 的情况下,我能想到的任何指令都没有任何不允许的相同寄存器操作数。如果它是可编码的,它将有一些明确定义的行为.有一些组合不太可能有用,比如div dx,保证会引发#DE异常,将DX:AX除以DX,例如结果永远无法放入 AX。