MOVSX 汇编指令是如何工作的?

Posted

技术标签:

【中文标题】MOVSX 汇编指令是如何工作的?【英文标题】:How does MOVSX assembly instruction work? 【发布时间】:2015-10-21 20:45:18 【问题描述】:

汇编指令MOVSX 在以下示例中如何工作:

MOVSX ECX,BYTE PTR DS:[EDX]

在这种情况下,这里是寄存器的状态:

ECX = 0000000F   
EDX = 0012FD9F 

根据我的想法,它需要 [EDX] = 9F 的最后一个字节,将其移动到 ECX,然后对其进行符号扩展以匹配 16 位 = 0000009F。但是,实际结果是 00000016。有人可以帮忙解释我哪里错了吗?

【问题讨论】:

旧问题和答案在下面有所帮助,但对于现在阅读本文的人来说,您的符号扩展名在这里并不完全正确(如果这是要使用的正确字节)。 0x9F = 1001 1111 因此,您的符号扩展位应该是位“1”而不是位“0”。 【参考方案1】:

这部分正确。然而:

BYTE PTR DS:[EDX] 获取 位于 EDX 中保存的地址的字节。这个字节被复制到ECX 到最低有效字节中,其余的用字节的符号填充。

对于你意想不到的结果,这意味着在内存地址10x12FD9F 字节0x16 位于。


注意事项:

这里不需要段覆盖前缀DS:[EDX] 自动引用 DS

1这里的“内存地址”指的是虚拟内存或物理内存

【讨论】:

【参考方案2】:

许多 Intel/AMD x86 指令以“modrm”格式提供 - 它们有两个操作数,其中一个必须是寄存器,另一个可能是寄存器或内存引用,其地址由指令编码的 modrm 字节,并且可能由指令的后续字节,例如 sib(缩放索引字节)和立即常量/内存偏移量。还有一个可能的段前缀字节。

通常这些是 reg,reg/mem 指令,格式为

   rsrcdst += rsrc
or
   rsrcdst += Memory[ ... addressessing mode ...]

但是 x86 汇编代码对于这些指令的 reg,reg 和 reg,mem 形式没有单独的操作码/指令助记符。操作数是寄存器还是内存位置,在汇编器中由汇编语法指示。

在这种情况下,你的汇编代码是

MOVSX ECX,BYTE PTR DS:[EDX]

指令操作码为MOVSX。

目标操作数是寄存器ECX。

源操作数是“BYTE PTR DS:[EDX]”。这是一个内存引用由几件事表明:(1)“[EDX]”周围的方括号 - 方括号是 Memory[...address...] 的简写。 (2)“DS:”前缀,表示它在数据段中。寄存器操作数没有这样的段前缀。 (3) “BYTE PTR” - 表示“获取 'DS:[EDX]' 指定的内存地址,并将其解释为引用内存中的 8 位字节”。

我怀疑你真正想要的是

MOVSX ECX,DL

“DL”是 32 位寄存器 EDX 低 8 位的名称。 IE。 DL=EDX.bits[7:0]。不幸的是,x86 汇编器通常不接受像“EDX.bits[7:0]”这样的语法(除非我写了它们),所以你必须知道子寄存器的历史名称:

AL = EAX.bits[7:0]
AH = EAX.bits[15:8]
AX = EAX.bits[15:0]
EAX = 32 bit register that "covers" all of the above

等等:BL、CL、DL、DI、...

【讨论】:

以上是关于MOVSX 汇编指令是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

会汇编 符号填充指令MOVSX 的进一下

汇编指令学习(MOV,MOVSX,MOVZX,LEA,XCHG)

汇编指令

MOVSX装配说明如何工作?

汇编指令集

汇编语法