MOV 指令将数据从内存提取到 x86 程序集中的内存



我已经反汇编了一个使用 Cscanf函数的x86 elf 二进制文件
以下是与scanf相关的反汇编代码块:

0x0804857a      89442404       mov dword [esp + 0x4], eax  
0x0804857e      c70424b28604.  mov dword [esp], 0x80486b2                                 
0x08048585      e8eafdffff     call sym.imp.scanf  

通过gdb检查,地址0x80486b2处的内存包含数据0x7325(ASCII代码中的">%s"字符串)。
因此,这段代码显然是在堆栈上以相反的顺序推送scanf参数,以便使用这两个参数调用scanf
这通常用 C 语言编码为scanf ("%s", &somevar);

鉴于汇编代码,我在这里所期望的是常0x80486b232 位表示形式被加载到堆栈指针指向的地址中......
相反,mov指令已将地址0x80486b2处的任何内容的 32 位表示形式加载到堆栈指针指向的地址中......是吗?

所以我们基本上得到的是,mov刚刚将数据从一个内存位置移动到另一个内存位置,根据这个 x86 程序集介绍(在众多其他来源中)这是非法的(重点是我的):

在需要内存传输的情况下,源内存 内容必须首先加载到寄存器中,然后才能存储到 目标内存地址。

这里没有使用登记册作为中介。
这怎么可能?

如果我理解得很好,这里的mov指令将地址0x80486b2处的任何内容的 32 位表示形式加载到堆栈指针指向的地址中......是吗?

不。指令

mov dword [esp], 0x80486b2

0x80486B2的即时值复制到寄存器ESP指向的地址。这个地方是传递给scanf函数的第一个参数。

所以我们基本上得到的是mov刚刚将数据从一个内存位置移动到另一个内存位置, [...]

不。该指令将立即的 32 位值移动到内存位置。在这种情况下,MOV 的指令签名为:

MOV r/m32, imm32        Move imm32 to r/m32.

0x80486b2写入寄存器 ESP 指向的 DWORD 内存地址。

指令mov dword [esp + 0x4], eax确实将第二个参数从EAX传递到scanf

指令mov dword [esp], 0x80486b2将 32 位即时值0x80486b2移动到 ESP 指向的 32 位内存位置。 如果它将存储地址0x80486b2的 32 位值移动到目标中,则它将被写入为mov dword [esp], dword [0x80486b2]。但是,这不是 MOV 指令允许的操作数组合。

请注意,您的反汇编使用的是 NASM 语法。

最新更新