Assembly MOVSX组装指令是如何工作的?

Assembly MOVSX组装指令是如何工作的?,assembly,x86,mov,Assembly,X86,Mov,在以下示例中,汇编指令MOVSX是如何工作的: MOVSX ECX,BYTE PTR DS:[EDX] 在这种情况下,以下是寄存器的状态: ECX = 0000000F EDX = 0012FD9F 根据我的想法,它需要[EDX]=9F的最后一个字节,将其移动到ECX,然后对其进行符号扩展以匹配16位=0000009F。然而,实际结果是00000016。有人能解释一下我错在哪里吗?部分正确。然而: 字节PTR DS:[EDX]获取位于EDX中保存的地址的字节。该字节被复制到ECX的最

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

MOVSX ECX,BYTE PTR DS:[EDX]
在这种情况下,以下是寄存器的状态:

ECX = 0000000F   
EDX = 0012FD9F 

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

部分正确。然而:

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

对于意外的结果,这意味着在内存地址1
0x12FD9F
中找到了字节
0x16


注:

  • 此处不需要段覆盖前缀
    DS:
    <代码>[EDX]自动引用
    DS


1“内存地址”是指此处的虚拟内存或物理内存

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

通常这些是reg、reg/mem指令的形式

   rsrcdst += rsrc
or
   rsrcdst += Memory[ ... addressessing mode ...]
但是x86汇编代码对于这些指令的reg、reg和reg、mem形式没有单独的操作码/指令助记符。在汇编程序中,操作数是寄存器还是内存位置由汇编语法指示

在本例中,您的汇编代码是

MOVSX ECX,字节PTR DS:[EDX]

指令操作码是MOVSX

目标操作数是寄存器ECX

源操作数为“字节PTR DS:[EDX]”。这是一个内存引用,可以通过以下几点来表示:(1)“EDX]”周围的方括号-方括号是内存[…地址…]的缩写。(2) “DS:”前缀,表示它位于数据段中。寄存器操作数没有这样的段前缀。(3) “BYTE PTR”-表示“获取由'DS:[EDX]'指定的内存地址,并将其解释为引用内存中的8位字节”

我怀疑你真正想要的是

MOVSX ECX,DL
“DL”是32位寄存器EDX低8位的名称。也就是说,DL=EDX.位[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,…

下面的老问题和答案很有帮助,但对于现在阅读本文的人来说,您的符号扩展名并不完全正确(如果这是正确的字节)
0x9F=1001111
因此,符号扩展位应为位“1”,而不是位“0”