2016-06-21 34 views
1

我的問題涉及RET64位模式和它們的操作數大小,它指定有多少信息從堆棧彈出到RIP以及RSP增加了多少字節的指令。RET默認的操作數大小是多少?

我注意到一些彙編程序留下了Intel定義的默認操作數大小。即近返回64位,遠遠回32位:

1   ; Assembled with NASM 2.12 command "nasm TestRET.asm -l TestRET.lst" 
2      BITS 64 
3 00000000 66CF  IRETW ; Opsize 16. 
4 00000002 CF   IRETD ; Opsize 32. 
5 00000003 48CF  IRETQ ; Opsize 64. 
6 00000005 66CF o16 IRET ; Opsize 16. 
7 00000007 CF  o32 IRET ; Opsize 32. 
8 00000008 48CF o64 IRET ; Opsize 64. 
9 0000000A CF   IRET ; Opsize 32, default. 
10     
11 0000000B 66CB o16 RETF ; Opsize 16. 
12 0000000D CB  o32 RETF ; Opsize 32. 
13 0000000E 48CB o64 RETF ; Opsize 64. 
14 00000010 CB   RETF ; Opsize 32, default. 
15     
16 00000011 66C3 o16 RETN ; Opsize 16. 
17 00000013 C3  o32 RETN ; Opsize 32 should not be available, NASM error? 
18 00000014 48C3 o64 RETN ; Opsize 64, REX.W ignored as RETN is promoted to 64 bits. 
19 00000016 C3   RETN ; Opsize 64, default. 

我不是在寫呼叫門和任務門經歷,但我認爲默認的操作數的大小應與段大小,這是64對應在64位模式下。

程序員在沒有進一步規範的情況下使用IRET,RETF和RETN時,希望從64位模式的彙編程序得到什麼操作數大小?

+0

誰知道?我懷疑有人做過調查。你真正的問題是什麼? –

+0

@RossRidge我的程序是否應該將RETF轉換爲CB或48CB? – vitsoft

+0

你的程序是彙編程序?我認爲它不會太重要,實際上沒有任何理由在64位代碼中編寫遠程返回。此外,RETF不是正式的指令,所以如果你記錄它,你可以做任何你想做的事情。 –

回答

1

假設編寫一個asm源文件中的ret將組合成一個單字節指令。

IDK爲什麼有人會在64位代碼中使用retf,所以我對此沒有任何意見。


在仔細閱讀您的表格後,我會看到您對NASM操作數大小覆蓋的看法。它不會特別針對RETN之類的說明修改器,導致產生僞造行爲,如o64 retn產生REX.W = 1前綴(48 C3)。

我認爲我們應該將NASM的o32前綴理解爲「16位代碼中的操作數大小前綴,否則不管」,而不管它應用於哪個指令,並且永遠不會暗示REX.W = 0(因爲它不無論如何工作push/pop)。

而且類似地,o64的確意味着應用REX.W = 1,而不管它使用什麼指令。即它不會在像pushpop之類的insn上省略它,是嗎?



的ISA被設計成單字節指令ret 「工作」。您在正常的ret上不需要REX前綴。如the instruction set manual's ret entry中所述:

在64位模式下,該指令的默認操作大小是堆棧地址大小,即64位。這適用於接近收益,而不是很遠的收益; far return的默認操作大小是32位。

這與在長模式下push/pop默認爲64位操作數大小類似。 (並且,與手冊中的暗示相反,REX.W=0無法編碼32位推/壓)。

AMD通常試圖保持簡單的解碼。例如movsxd r64, r/m32需要一個REX前綴(否則它只是作爲一個潛在效率較低的mov運行),但對於像push/pop和ret這樣的常見指令,他們使用這樣的設計選擇保存了代碼大小。

+2

a16 retf和a32 retf的場景 - 您試圖返回到16位或32位代碼。 a64 retf,這很困難,但假設你剛剛用LGDT重載了GDT並且表中的代碼段描述符不一樣,那麼你需要強制CS重新加載。在這種情況下,a64 retf是有道理的。 –

+1

@MichaelPetch Tnx,需要'o64 IRET(48CF)'的另一個例子可能是從加載的代碼觸發的中斷處理程序返回4GB以上。 BTW不應該閱讀'o64,o32,o16'而不是'a64,a32,a16'?正如POP中所記錄的,AFAIK a64(地址大小前綴67)在64位模式下基於RSP的指令上沒有意義。這裏堆棧指針大小固定爲64位。 – vitsoft

+0

是的@vitsoft應該都不是'a'。是我昨晚做出的最後一條評論,甚至沒有注意到錯字。 –

相關問題