X86:`movsxd rdx,edx` 指令是什么意思?

R44*_*444 7 assembly x86-64 mov

我一直在玩intel mpx,发现它添加了一些我无法理解的指令。例如(英特尔格式):

movsxd rdx,edx
Run Code Online (Sandbox Code Playgroud)

我发现了这个,它谈到了一个类似的指令 - MOVSX.

从那个问题,我对这条指令的解释是,它需要双字节(这就是为什么有din movsxd)并将其复制到rdx寄存器(在两个最低有效字节中)并用该双字节的符号填充其余部分。

我的解释是否正确(我认为我错了)?如果没有,你能告诉我发生了什么吗?

Mic*_*tch 10

您的代码是 64 位的。如果您查看 的指令集架构 (ISA) 手册MOVSXD,则 64 位变体定义为:

 MOVSXD r64, r/m32       Move doubleword to quadword with sign-extension.
Run Code Online (Sandbox Code Playgroud)

这是 64 位代码中的指令,它将 32 位寄存器或地址转换为 32 位值,并将其符号扩展移动到 64 位寄存器中。符号扩展是取源的最高位(符号位)的值,并用它来填充目标的所有高位。

movsxd rdx,edx查看EDX 的第31 位(最高位)并将目标的高 32 位设置为该值并按原样复制低 32 位。如果在EDX 中设置符号位,则 64 位寄存器的高 32 位将设置为 1。如果符号位清零,则RDX的高 32 位将为 0。

例如,假设EDX的值为0x80000000。第 31 位为 1。作为一个有符号数,即-2147483648。如果你这样做movsxd RDX, EDXRDX 中的值将是0xFFFFFFFF80000000. 作为一个有符号的 64 位值仍然代表-2147483648.

如果EDX0x7fffffff(signed value +2147483647) 并且第 31 位为 0,那么RDX 中的值将0x000000007fffffff仍然代表有符号数+2147483647。正如您所看到的,符号扩展在更宽的寄存器的高位上保留了符号位,以便保留目标的符号性。

  • 更有趣的是存在没有“REX.W”(和 32 位版本)的“movsxd r16, r/m16”又名“63 /r”。需要一种新的编码,但谁知道他们为什么更改指令名称,毕竟通过在`movsx eax, ax` 之前添加操作数大小覆盖前缀,可以创建`movsx ax, ax` 所以它不像任何新东西。 (3认同)