在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汇编语言的书籍中查找答案,而教程应该向您介绍括号/括号语法的重要性。请参阅x86标记wiki获取一些教程和其他通用参考信息。
'mov(%rax),%eax'从内存中提取,'mov%rax,%eax'由于操作数大小不匹配而无效,但是如果它是有效的,它将简单地从一个寄存器传输到另一个寄存器。 – Jester