mov指令在x86程序集中从内存中获取数据到内存

pro*_*rsn 0 memory x86 assembly stack mov

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

0x0804857a      89442404       mov dword [esp + 0x4], eax  
0x0804857e      c70424b28604.  mov dword [esp], 0x80486b2                                 
0x08048585      e8eafdffff     call sym.imp.scanf  
Run Code Online (Sandbox Code Playgroud)

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

在给定汇编代码的情况下,我所期望的是,常量32位表示形式 0x80486b2被加载堆栈指针所指向的地址中 ......
但是,该mov指令已经加载了32位表示的任何处于地址 0x80486b2 堆栈指针指向的地址 ......是吗?

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

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

此处没有注册用作中间人.
怎么可能?

zx4*_*485 5

如果我理解的话,mov这里的指令将地址为0x80486b2的32位表示加载到堆栈指针指向的地址中......是吗?

不.指令

mov dword [esp], 0x80486b2
Run Code Online (Sandbox Code Playgroud)

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

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

否.指令将立即的32位值移动到存储位置.在这种情况下,MOV的指令签名是:

MOV r/m32, imm32        Move imm32 to r/m32.
Run Code Online (Sandbox Code Playgroud)

该值0x80486b2将写入寄存器ESP指向的DWORD存储器地址.

指令mov dword [esp + 0x4], eax并通过从所述第二参数EAXscanf.