2014-06-14 126 views
2

我剛剛發現push指令可以有一個立即的字節,字,dword參數,而且每一個都有不同的操作碼。我正在閱讀的書中沒有例子,所以我不明白彙編程序如何區分這三種類型。例如,如果我寫push 12h它將如何被彙編器解釋以及堆棧上會發生什麼?x86彙編,堆棧推入指令

+0

一個設想的*完整目的*當然是找出與您的輸入相對應的操作碼序列。給它一些信用。 –

+0

+1在我之前問這個問題!我會給NASM一些信用:-) – carveone

回答

1

彙編程序爲每個變體生成不同的操作碼。它將在決定將哪個操​​作碼組合到之前檢查參數。由於您示例中的12h不是寄存器的名稱,但符合數字的十六進制表示的特徵,因此推斷需要推送立即值,並生成相應的操作碼以及二進制值作爲指令。它還將檢查該論證是否被方括號括起來,用於間接。 對於CPU,執行該代碼時,這些不同的變體實際上是不同的指令 - 雖然在執行時共享一些共同點。

檢查參數以確定它們的性質是彙編程序對許多指令的操作,除了推送以外,也是爲了相同目的:決定需要爲指令選擇哪個操作碼。

2

這取決於彙編程序。它可以選擇操作碼的最小操作數字段足夠大,以保存即時值。它也可能要求你告訴它你想使用哪個變體。

例如,NASM將push 12h組裝成6A 12push byte 12h)。

如果您想要得到push imm16變體,你會說push strict word 12h(如果你不希望NASM優化指令到字節推送,則需要strict)。

請注意,立即字節push實際上並未將字節推送到堆棧。在被推動之前,該值將被符號擴展到至少16位(這發生在執行期間,而不是在編譯期間)。

+0

如果它將字節擴展爲單詞或雙字,是否有立即字節指令的原因? – user1978522

+1

縮小代碼大小將是一個原因。 – Michael

+0

我對此有兩點評論,我爲其他人感興趣:當我在Gnu AS中編譯「push 1」時,它會變成push imm8指令「6A01」。但這有點誤導 - 我認爲它會像推一個字節或一個字一樣瘋狂。但事實並非如此,它推動了32位。 「push 1」,然後「pop eax」在eax中返回1。所以,邁克爾是正確的:-) – carveone