NASM返回如下錯誤:「在64位模式下不支持指令」,我無法弄清楚該怎麼做。主題指令是彈出和推送命令。我可以使用什麼來代替它們,或者有其他方法可以解決此問題嗎?64位模式不支持PUSH和POP指令
最好的問候......(我使用64位系統 - 英特爾酷睿i7處理器)
NASM返回如下錯誤:「在64位模式下不支持指令」,我無法弄清楚該怎麼做。主題指令是彈出和推送命令。我可以使用什麼來代替它們,或者有其他方法可以解決此問題嗎?64位模式不支持PUSH和POP指令
最好的問候......(我使用64位系統 - 英特爾酷睿i7處理器)
總體思路是,你通常推而大如當前流行詞寄存器大小,所以你不能在64位模式下推送32位寄存器;相反,您可以推送並彈出整個64位寄存器,因此這是push rax
而不是push eax
。內存引用也是如此 - 您可以使用push qword ptr[rax]
,但不能使用push dword ptr[rax]
。
但是:即使在64位模式仍可以推:
push ax
)和存儲器的引用(push word ptr[rax]
);push 1
它將使用最緊湊的編碼進行編碼,該編碼將爲6A01
,即imm8操作數)。fs
和gs
段寄存器但不的cs
,ds
,es
,ss
寄存器(其沒有真正在64位模式中使用)。在所有這些情況下,小於64位的值(如push al
)在符號堆棧上被符號擴展並推送爲64位值。這可以讓你做一個push -1
(6AFF
),匹配pop rax
- 那就像你期望的那樣,它的工作原理與mov rax,-1
完全一樣。
作爲一個例外,段寄存器或者是零-擴展或推入堆棧並且進行16位移動(即堆棧上的另一個48位未被修改);這並不是什麼大問題,因爲pop fs
和pop gs
只是放棄這些額外的位。
最後,可以推16位或32個值(那些在上面的列表中指定)在64位模式而不它們延伸到64位 - 從而移動的只是2堆棧指針或4字節。這是用66h
或REX.W
前綴編碼的,但是,如果您不小心,可能會使您產生未對齊的堆棧。
除了可以推送r/m16和r/m64而不是r/m32的事實之外,事實上可以推送imm8,imm16和imm32而不是imm64是很奇怪的太。你不能推CS,DS,ES或SS,但你可以推FS和GS。相當不一致的IMO。 –
@RudyVelthuis:它*很不一致,儘管在這個瘋狂中有一些方法。不能推送一個* imm64 *與其餘的指令集模糊不清 - 我知道接受* imm64 *的唯一指令是'mov r64,imm64'(實際上,它是* imm64的唯一匹配*在英特爾手冊中的整個指令集描述中)。除了* fs *和* gs *之外的段寄存器不再用於64位模式,所以它們不能被推送就不足爲奇了。 –
我明白「瘋狂背後的方法」。但有時候它會讓人感到困惑。特別是你可以推/ 16位而不是32位的項目。 –
顯示您的代碼,否則問題將無效。 「尋求調試幫助的問題(」爲什麼不是這個代碼工作?「)必須包含所需的行爲,特定的問題或錯誤以及在問題本身中重現問題所需的最短代碼。沒有明確問題陳述的問題對其他讀者無益' –