2016-12-19 3076 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獲取一些教程和其他通用參考信息。

相關問題