2012-07-01 89 views
0

我需要選擇正確的函數調用函數foo,而不是寫在c中。 foo得到1個參數0x100fa500。彙編中的推送指令(英特爾8086)

第一個答案是:

sub esp,2 
mov word[esp],0xa500 
sub esp,2 
mov word[esp] , 0x100f 
call foo 
add esp 4 

與第二:

sub esp,2 
mov word[esp],0x100f 
sub esp,2 
mov word[esp] , 0xa500 
call foo 

爲什麼第二次是真的嗎?我認爲第一個實現右推參數,然後調用

+0

標記爲家庭作業嗎? – ndkrempel

回答

3
從末失蹤 add esp, 4

除此之外,第二個版本是正確的,因爲英特爾架構是little-endian的。這意味着一個DWORD被存儲在內存中,其最低有效BYTE或WORD佔用較低的內存地址。在你的情況下,0xA500是DWORD中最不重要的WORD,第二個版本正確地將它放在堆棧的一個4字節區域的低2字節中。

+0

但是不是從高地址開始堆棧? 我的意思是,如果我將執行第一個代碼,我會得到: 10在堆棧的最低地址和00最高。我會得到,如果我這樣做:推0x100fa500。我對嗎? 這也是什麼 – user1462787

+0

@ user1462787:你所說的一切都與一個大端的體系結構一致,在這裏並不是這樣。你試圖把10放在堆棧的最低地址的事實已經是錯誤的。實際上,第一個代碼會將0F放在堆棧的最低地址中 - 事實上,您犯了兩次相同的錯誤(一次是DWORD中的字節順序,與問題要求相關,一次是字節順序一個WORD,與'mov'指令的操作有關。) – ndkrempel

+0

@ user1462787:或許你的困惑與堆棧向下增長有關。從這個意義上講,堆棧是'向後'的,但堆棧中的單個數據項以正常順序存儲,否則使用標準的DWORD和WORD大小的'mov's將無法正確訪問它們。 – ndkrempel

0

它取決於調用約定,但對於「cdecl」,由調用者清理堆棧。這意味着這是你的第一個答案是正確的,因爲它「添加了特別的,4」。然而,就像他在回答中的ndkrempel通知一樣,參數應該像第二個答案一樣以小尾數的形式傳遞。

http://en.wikipedia.org/wiki/X86_calling_conventions

+0

我認爲調用者堆棧清理與否僅僅是一個錯誤的問題。注意「mov」的順序不同 - 我認爲這是問題的主要核心。 – ndkrempel

+0

@ndkrempel:我認爲你是對的。我編輯了我的答案。這確實可能是一個家庭作業問題:-) –