2016-12-19 1671 views
-1

mov (%rax),%eaxmov %rax,%eax有什么区别?我确信这是一个简单的问题,但我无法在任何地方找到答案。“mov(%rax),%eax”和“mov%rax,%eax”有什么区别?

这是促使我的问题的原代码:

mov -0x8(%rbp),%rax 
mov (%rax),%eax 
lea (%rax,%rax,1),%edx 
mov -0x8(%rbp),%rax 
mov %edx,(%rax) 
mov -0x8(%rbp),%rax 
mov (%rax),%eax 
+4

'mov(%rax),%eax'从内存中提取,'mov%rax,%eax'由于操作数大小不匹配而无效,但是如果它是有效的,它将简单地从一个寄存器传输到另一个寄存器。 – Jester

回答

1

在AT & T语法,指令:

mov (%rax), %eax     # AT&T syntax 

,或等同于Intel语法:

mov eax, DWORD PTR [rax]   ; Intel syntax 

解除引用存储在rax的存储器地址,读出从该存储器地址的32位的值,并将其存储在寄存器eax

因为被取消引用的内存地址存储在rax中,所以它可以是一个64位地址,这在64位操作系统上运行时是必需的。

但是,数据指向的那个内存地址只有32位大小,所以它可以存放在32位的eax寄存器中。

请注意,该指令会隐式地将rax寄存器的高32位清零,因此低32位(称为eax)将包含加载的数据,而高32位的一半将为空。

T语法中的圆括号(或英特尔语法中的方括号)是您的线索,表示此指令将寄存器的内容视为指针。
这是什么使得它从不同的,例如:

mov %rcx, %rax     # AT&T syntax 
mov rax, rcx      ; Intel syntax 

这只是拷贝rcx寄存器的内容到rax寄存器。没有取消引用。寄存器中的值直接起作用。

注意上面的例子是类似其他例如从你的问题:

mov %rax, %eax     # AT&T syntax (INVALID!) 
mov eax, rax      ; Intel syntax (INVALID!) 

但不完全相同。这最后一种情况实际上是无效指令,因为存在操作数大小不匹配。如果该指令有效,该指令将复制64位rax寄存器的内容到32位eax寄存器中。当然,这是不可能的。缩小转换是不允许的,所以它不会组装。

如果你真的想要做到这一点,你将不得不决定你想扔掉rax的64位值的哪一部分。如果您决定丢弃较高位并仅将较低位复制到eax,则不需要执行任何操作,只需直接使用eax即可。但是,如果你想扔掉的低位,并且只使用了高位,应该首先由32


注意,这是一个相当简单的,一般性参考资料的问题做右移。您可以在任何有关x86汇编语言的书籍中查找答案,而教程应该向您介绍括号/括号语法的重要性。请参阅标记wiki获取一些教程和其他通用参考信息。

相关问题