Che*_*mez 4 x86 assembly x86-64 cpu-registers
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
Run Code Online (Sandbox Code Playgroud)
在 AT&T 语法中,指令:
Run Code Online (Sandbox Code Playgroud)mov (%rax), %eax # AT&T syntax
或者,等效于 Intel 语法:
Run Code Online (Sandbox Code Playgroud)mov eax, DWORD PTR [rax] ; Intel syntax
取消引用存储在rax
中的内存地址,从该内存地址读取一个 32 位值,并将其存储在eax
寄存器中。
因为被取消引用的内存地址存储在 中rax
,所以它可以是 64 位地址,这在 64 位操作系统上运行时是必需的。
但是那个内存地址指向的数据只有32位大小,所以可以存放在32位eax
寄存器中。
请注意,此指令会将rax
寄存器的高 32 位隐式清零,因此低 32 位一半(称为eax
)将包含加载的数据,而高 32 位一半将为空。
AT&T 语法中的括号(或 Intel 语法中的方括号)是您这条指令将寄存器内容视为指针的线索。
这就是它不同于例如:
Run Code Online (Sandbox Code Playgroud)mov %rcx, %rax # AT&T syntax
Run Code Online (Sandbox Code Playgroud)mov rax, rcx ; Intel syntax
这只是将rcx
寄存器的内容复制到rax
寄存器中。没有取消引用。寄存器中的值直接作用。
请注意,上面的示例类似于您问题中的另一个示例:
Run Code Online (Sandbox Code Playgroud)mov %rax, %eax # AT&T syntax (INVALID!)
Run Code Online (Sandbox Code Playgroud)mov eax, rax ; Intel syntax (INVALID!)
但不完全相同。最后一种情况实际上是无效指令,因为存在操作数大小不匹配。如果有效,则指令会将 64 位rax
寄存器的内容复制到 32 位eax
寄存器中。当然,这是不可能的。不允许缩小转换,因此它不会组装。
如果您真的想这样做,则必须决定rax
要丢弃64 位值的哪一半。如果您决定丢弃高位并仅将低位复制到eax
,则无需执行任何操作 — 直接使用eax
即可。但是,如果您想丢弃低位而只使用高位,则应首先右移 32。
请注意,这是一个相当简单的一般参考问题。您可以在任何关于 x86 汇编语言的书中查找答案,并且教程应该会教您有关括号/方括号语法的重要性。有关一些教程和其他一般参考信息,请参阅x86标签 wiki。
归档时间: |
|
查看次数: |
13899 次 |
最近记录: |