mov eax, dword ptr [eax]是什么意思?

11
我了解 dword ptr 是一个大小指令,表示正在移动的内容的大小。我知道 mov eax, eax 是 nop 代码的一种形式,但它是什么意思呢?
我认为它会交换 eax 的地址和内部十六进制值,但我不确定为什么会发生这种情况。
4个回答

22

它使用EAX加载原始指向的DWORD值。

用C术语来说,它是按照以下方式取消引用最初保存在EAX中的值:"eax = *eax"


2
在我的观点中,“解引用”指针是最简单正确的答案。 - xmojmr

11

mov eax, eax 这条指令可能是一个无操作代码,但这并不是你在这里看到的情况。正如 [] “取内容”的符号所示,您正在从内存中加载内容。

它将eax加载为内存中(在此情况下为32位dword)当前由eax指向的内容。

也许一个图形化的图片会有所帮助:

Before:
    eax:                 0x12345678
    memory @ 0x12345678: 0xffffffff

After:
    eax:                 0xffffffff
    memory @ 0x12345678: 0xffffffff

关于可能的用途,毫无疑问有很多。立刻浮现在脑海中的一个是链表结构,其中单个元素类似于以下伪汇编代码:

next:      word     ?         ; one word.
payload:   byte     ?(32)     ; 32 bytes.

如果eax被用作指向这些元素之一的指针,那么获取下一个元素的指令如下:

mov eax, dword ptr [eax]

1
哦,我其实不知道 [] 表示内容。那么没有括号可以执行 dword ptr eax 吗? - user2893243
1
@user2893243,那样做没有意义。eax是一个明确的32位值,而您可能想要从内存中加载单个字节、字、双字或(至少在x64中)四字(对于rax而不是eax)。 - paxdiablo
1
啊,好的。所以如果我想要执行 word ptr eax,这本来就没有意义,那么我只需要写成 ax 就可以了。顺便问一下,你知道有哪些关于汇编的好书吗? - user2893243
2
顺便说一句,这种从指针寄存器加载到自身的方法经常出现在链式数据结构(例如链表)中,因为它允许编译器将一个寄存器用作“当前元素”指针。 - Leeor
@Leeor:很好的使用案例,我已经把它加到答案里了,虽然有点晚了 :-) - paxdiablo

5

dword ptr [eax] - 指向地址为eax的内存,因此该语句将从内存中复制32位值到 eax


1
关于为什么会发生这种情况,这取决于上下文。
例如,可以使用此方法将堆栈上的[eax]值加载到函数调用的参数中。该操作无法一次完成(例如mov dword [esp + 4], dword [eax]中不能有两个内存引用),因此分为两个指令:
mov eax, dword [eax]
mov dword [esp + 4], eax

为此,您通常会执行push dword ptr [eax],具体取决于您处理堆栈参数的策略。在代码中找到这个的更可能原因是对链表或树进行循环。但是,如果它不在循环中,当您后面不再需要指针值时,它确实可以是任何取消引用。比如只是通过一两个间接寻址来获取某些内容。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接