我剛剛發現push指令可以有一個立即的字節,字,dword參數,而且每一個都有不同的操作碼。我正在閱讀的書中沒有例子,所以我不明白彙編程序如何區分這三種類型。例如,如果我寫push 12h
它將如何被彙編器解釋以及堆棧上會發生什麼?x86彙編,堆棧推入指令
回答
彙編程序爲每個變體生成不同的操作碼。它將在決定將哪個操作碼組合到之前檢查參數。由於您示例中的12h不是寄存器的名稱,但符合數字的十六進制表示的特徵,因此推斷需要推送立即值,並生成相應的操作碼以及二進制值作爲指令。它還將檢查該論證是否被方括號括起來,用於間接。 對於CPU,執行該代碼時,這些不同的變體實際上是不同的指令 - 雖然在執行時共享一些共同點。
檢查參數以確定它們的性質是彙編程序對許多指令的操作,除了推送以外,也是爲了相同目的:決定需要爲指令選擇哪個操作碼。
這取決於彙編程序。它可以選擇操作碼的最小操作數字段足夠大,以保存即時值。它也可能要求你告訴它你想使用哪個變體。
例如,NASM將push 12h
組裝成6A 12
(push byte 12h
)。
如果您想要得到push imm16
變體,你會說push strict word 12h
(如果你不希望NASM優化指令到字節推送,則需要strict
)。
請注意,立即字節push
實際上並未將字節推送到堆棧。在被推動之前,該值將被符號擴展到至少16位(這發生在執行期間,而不是在編譯期間)。
如果它將字節擴展爲單詞或雙字,是否有立即字節指令的原因? – user1978522
縮小代碼大小將是一個原因。 – Michael
我對此有兩點評論,我爲其他人感興趣:當我在Gnu AS中編譯「push 1」時,它會變成push imm8指令「6A01」。但這有點誤導 - 我認爲它會像推一個字節或一個字一樣瘋狂。但事實並非如此,它推動了32位。 「push 1」,然後「pop eax」在eax中返回1。所以,邁克爾是正確的:-) – carveone
- 1. 彙編堆棧指針AVR
- 2. x86 - 將8位值推入堆棧
- 3. 相同x86彙編指令的不同
- 4. x86彙編:MOVSD指令問題
- 5. C inline彙編x86 fbstp指令
- 6. 彙編語言x86 JL指令
- 7. x86彙編指令:CALL *註冊
- 8. ARM彙編 - 監視器堆棧指針
- 9. 6502彙編 - RTS命令和堆棧
- 10. x86 - CALL指令是否總是將EIP指向的地址推送到堆棧?
- 11. x86堆棧指針指向哪裏?
- 12. 堆棧中的預留字節:x86彙編(64位)
- 13. 在x86彙編代碼中追蹤堆棧
- 14. x86彙編:爲什麼我需要堆棧框架?
- 15. 彙編語言 - 堆棧機
- 16. 彙編堆棧3函數
- 17. 彙編堆棧訪問
- 18. 彙編堆棧持久性
- 19. 堆棧在NASM彙編
- 20. x86彙編棧佈局混亂
- 21. x86彙編堆內存分配
- 22. x86程序集 - masm32:將變量推入堆棧的問題
- 23. 彙編級編程中的堆棧指針
- 24. 當我向程序集x86中插入新指令時堆棧的幀大小?
- 25. POPF x86彙編
- 26. CIL堆棧交換指令
- 27. DCD指令和IRQ堆棧
- 28. 將鏈表推入堆棧
- 29. 將整數推入堆棧
- 30. ARM彙編指令
一個設想的*完整目的*當然是找出與您的輸入相對應的操作碼序列。給它一些信用。 –
+1在我之前問這個問題!我會給NASM一些信用:-) – carveone