Assembly 是否可以将同一寄存器用作同一指令中的内存指针和数据?

Assembly 是否可以将同一寄存器用作同一指令中的内存指针和数据?,assembly,x86,x86-16,Assembly,X86,X86 16,例如,在以下说明中: MOV [BX], BH 寄存器BH是寄存器BX的一部分。这没有问题,甚至没有任何理由认为它可能被禁止。(除了你的课本,显然是)。存储只读取地址寄存器和数据寄存器,并在该地址写入内存。 现代CPU中的寄存器读取通常是通过多端口寄存器文件完成的,多端口寄存器文件允许在同一时钟周期内完成两个或多个独立的读取。寄存器文件由SRAM构建,因此在同一时间读取同一组单元两次是没有问题的 mov bx,bh当然不合法,因为寄存器的宽度不同,而不是一个重叠mov cx,bh同样是非法的。

例如,在以下说明中:

MOV [BX], BH

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

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

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

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

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


在一些ISA中,某些指令对使用同一寄存器有限制,例如,较旧的ARM在乘法器使用同一寄存器作为输入输出时出现问题。但是像load或store这样的简单指令并不是那么奇怪

除了更新指针寄存器以及加载到不同寄存器的寻址模式之外。内特建议把ldrx0[X0],8作为不允许的例子
ldr-x1[x0],8
does
x1=mem[x0];x0+=8
(),且不允许使用x1=x0

x86没有任何索引前/索引后显式寻址模式,但x86有push/pop,它隐式使用[E/R]SP作为地址,并使用一个显式数据操作数。手册准确地记录了和发生的情况。(如果可编码,则pop sp=
mov sp,[sp]

一般来说,如果该指令没有明确说明,您可以假定相同的寄存器(或重叠的部分寄存器)是操作数和/或地址的有效选择。


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

是的,这是允许的。使用此命令时是否存在任何风险或需要注意的事项?顺便说一句,我问这个问题是因为在我的课本上写着这是禁止的,这对我来说似乎不合逻辑,所以我想验证他们是否错了。@Deftera根本没有风险。指令(汇编中没有命令)完全按照它所说的做。另一种方法更有用:
MOV BH,[BX]
如果您不需要进一步的地址,那么就可以使用BH作为值。无论哪种方式,您都可以认为,如果您喜欢,在指令执行时,“输入”会被复制到某个临时位置,这样它就不会受到寄存器覆盖的影响。例如,使用ARM64上的写回前/后索引加载和存储,您可能无法执行
LDR X0[X0],8
,否则加载完成后会将8添加到X0。但在x86上它是完全安全的。你的课本上到底说了什么?你可能理解的与他们的意思不同。你的答案以“不,没有问题”开头,但从问题(至少现在是这样)来看,似乎应该改为“是的,没有问题”。