当我遇到 MOVZ 时我正在使用反汇编程序并且有点困惑,因为我之前只使用过 MOV。
ARMv8 ISA 手册当然解释了所有细节,并且 MOV 是其他三个的别名,具体取决于上下文,但也许有人可以在这里提供一些基本原理,并给出具体示例以加快学习过程。
该指令可以采用多种形式,具体取决于需要移动的值。如果值是寄存器或立即数,它会改变。如果它在寄存器中,那么它会产生一条ORR
指令 ( ORR <Xd>, XZR, <Wm>
)*。如果它使用SP
(堆栈指针),它会产生一条ADD
指令(ADD <Xd|XSP>, <Xn|XSP>, #0
)*。如果移动立即数,则它是 MOVZ、MOVK 或 MOVN 指令之一。
*这些是 64 位原型。
XZR
是零寄存器,其值始终为零。和共享由相同的数字 (31) 标识,这就是为什么XZR
当是目标或操作数时不能使用指令的原因。而是使用该指令。SP
ORR
SP
ADD
这两条指令有时一个接一个地使用。它们用于移动即时值。
MOVZ
将立即值(16 位值)移动到寄存器,立即值之外的所有其他位都设置为零。立即数可以向左移动0
,16
或. 移动一个立即数,但保持寄存器的其他位不变(用于保持)。例如,假设您需要将此值移动到 register 。首先,您将使用指令移动前 16 位(位 0 到 15),因此寄存器的其余位设置为零。然后您将移动第二个 16 位(位 16 到 31)32
48
MOVK
K
0x7fb7fb1f88
x0
MOVZ
MOVK
指令,因此之前移动的值(前 16 位)保留在寄存器中,您对其他剩余位执行相同操作。
instruction value of x0
mov x0, #0x1f88 | 0x1f88
movk x0, #0xb7fb, lsl #16 | 0xb7fb1f88
movk x0, #0x7f, lsl #32 | 0x7fb7fb1f88
MOVN
通常用于移动位掩码,这里N
代表否定。假设您要将位掩码移动0xffffffff0000ffff
到 x0。然后您将0xffff
向左移动 16,这将使值0x00000000ffff0000
。否定这个值变成 0xffffffff0000ffff。
这是一个例子:
instruction value of x0
MOVN x0, 0xFFFF, lsl 16 | 0xffffffff0000ffff