是否可以在同一条指令中使用同一个寄存器作为内存指针和数据?
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], 8
做 x1 = 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。
例如,在下面的指令中:
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], 8
做 x1 = 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。