mov 指令在 x86 汇编中将数据从内存获取到内存
mov instruction fetches data from memory to memory in x86 assembly
我反汇编了一个 x86 elf 二进制文件,它使用了 C scanf
函数。
这是与 scanf
相关的反汇编代码块:
0x0804857a 89442404 mov dword [esp + 0x4], eax
0x0804857e c70424b28604. mov dword [esp], 0x80486b2
0x08048585 e8eafdffff call sym.imp.scanf
检查gdb
,地址0x80486b2
处的内存包含数据0x7325
([=%s"字符串35=]ASCII码).
所以这段代码显然做的是 pushing scanf
参数在堆栈上以相反的顺序调用 scanf
这两个参数。
这通常在 C 中编码为 scanf ("%s", &somevar);
根据汇编代码,我在这里所期望的是 常量 0x80486b2
的 32 位表示被加载到堆栈指针指向的地址中...
相反,mov
指令加载了 32 位表示的 地址处的任何内容 0x80486b2
进入堆栈指针指向的地址……对吗?
所以我们基本上得到的是 mov
刚刚将数据从 内存位置 移动到另一个 内存位置 ,根据这个x86 assembly introduction(在众多其他来源中)是非法的(重点是我的):
In cases where memory transfers are desired, the source memory
contents must first be loaded into a register, then can be stored to
the destination memory address.
这里没有使用寄存器作为中介。
这怎么可能?
指令mov dword [esp], 0x80486b2
将32位立即数0x80486b2移动到ESP指向的32位内存位置。如果它将存储地址 0x80486b2 处的 32 位值移动到目标中,那么它将被写为 mov dword [esp], dword [0x80486b2]
。但是,这不是 MOV 指令允许的操作数组合。
请注意,您的反汇编使用的是 NASM 语法。
If I understand well, the mov
instruction here loaded the 32-bit representation of whatever was at the address 0x80486b2 into the address pointed to by the stack pointer ... Is that right ?
没有。指令
mov dword [esp], 0x80486b2
将立即数0x80486B2
复制到寄存器ESP
指向的地址。这个地方是传递给scanf
函数的第一个参数。
So what we basically get is that mov
has just moved around data from a memory location to another memory location, [...]
没有。该指令将立即数 32 位值移动到内存位置。本例中 MOV 的指令签名为:
MOV r/m32, imm32 Move imm32 to r/m32.
值0x80486b2
写入寄存器ESP指向的DWORD内存地址。
指令mov dword [esp + 0x4], eax
确实将第二个参数从EAX
传递给scanf
。
我反汇编了一个 x86 elf 二进制文件,它使用了 C scanf
函数。
这是与 scanf
相关的反汇编代码块:
0x0804857a 89442404 mov dword [esp + 0x4], eax
0x0804857e c70424b28604. mov dword [esp], 0x80486b2
0x08048585 e8eafdffff call sym.imp.scanf
检查gdb
,地址0x80486b2
处的内存包含数据0x7325
([=%s"字符串35=]ASCII码).
所以这段代码显然做的是 pushing scanf
参数在堆栈上以相反的顺序调用 scanf
这两个参数。
这通常在 C 中编码为 scanf ("%s", &somevar);
根据汇编代码,我在这里所期望的是 常量 0x80486b2
的 32 位表示被加载到堆栈指针指向的地址中...
相反,mov
指令加载了 32 位表示的 地址处的任何内容 0x80486b2
进入堆栈指针指向的地址……对吗?
所以我们基本上得到的是 mov
刚刚将数据从 内存位置 移动到另一个 内存位置 ,根据这个x86 assembly introduction(在众多其他来源中)是非法的(重点是我的):
In cases where memory transfers are desired, the source memory contents must first be loaded into a register, then can be stored to the destination memory address.
这里没有使用寄存器作为中介。
这怎么可能?
指令mov dword [esp], 0x80486b2
将32位立即数0x80486b2移动到ESP指向的32位内存位置。如果它将存储地址 0x80486b2 处的 32 位值移动到目标中,那么它将被写为 mov dword [esp], dword [0x80486b2]
。但是,这不是 MOV 指令允许的操作数组合。
请注意,您的反汇编使用的是 NASM 语法。
If I understand well, the
mov
instruction here loaded the 32-bit representation of whatever was at the address 0x80486b2 into the address pointed to by the stack pointer ... Is that right ?
没有。指令
mov dword [esp], 0x80486b2
将立即数0x80486B2
复制到寄存器ESP
指向的地址。这个地方是传递给scanf
函数的第一个参数。
So what we basically get is that
mov
has just moved around data from a memory location to another memory location, [...]
没有。该指令将立即数 32 位值移动到内存位置。本例中 MOV 的指令签名为:
MOV r/m32, imm32 Move imm32 to r/m32.
值0x80486b2
写入寄存器ESP指向的DWORD内存地址。
指令mov dword [esp + 0x4], eax
确实将第二个参数从EAX
传递给scanf
。