MOVSX装配说明如何工作?

Abu*_*nce 9 x86 assembly mov

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

MOVSX ECX,BYTE PTR DS:[EDX]
Run Code Online (Sandbox Code Playgroud)

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

ECX = 0000000F   
EDX = 0012FD9F 
Run Code Online (Sandbox Code Playgroud)

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

cad*_*luk 8

这部分是正确的.然而:

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

对于意外结果,这意味着在存储器地址1处找到 0x12FD9F该字节0x16.


笔记:

  • DS:此处不需要段覆盖前缀.[EDX]自动指的DS.

1 "内存地址"指的是虚拟或物理内存


Kra*_*lew 5

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

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

   rsrcdst += rsrc
or
   rsrcdst += Memory[ ... addressessing mode ...]
Run Code Online (Sandbox Code Playgroud)

但是 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
Run Code Online (Sandbox Code Playgroud)

“DL”是 32 位寄存器 EDX 的低 8 位的名称。即 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
Run Code Online (Sandbox Code Playgroud)

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