2012-02-04 58 views
8

我正在學習彙編語言。參數推送順序究竟是什麼?我理解它是如何將參數推入堆棧的,但左邊和右邊的部分是什麼意思?什麼左邊或右邊? 或者這僅僅是與命令的語義寫入方式有關,即:什麼是參數推送順序

mov ebp,esp; esp被移到ebp中,從右到左。

這是正確的還是有人能夠啓發我?

非常感謝!

回答

11

處理器不知道'函數參數'。因此,當你想寫f(a,b,c)時,你真的需要將參數推到某處。

這是約定。我知道在大多數x86機器上,函數參數從右到左被推入堆棧,即先c,然後b,然後a。

push c 
push b 
push a 
call f 

現在被調用函數可以使用ebx -1了,ebx - 2 b和ebx - 3對C。

你也可以建立一個約定:前兩個參數在寄存器ebxecx中,其餘的都在堆棧上。只要主叫方和被叫方同意,你就沒事。

7

除了xtofl的解釋,你可能想看看x86 calling conventions這張表。你會注意到,關於參數順序是幾乎所有的參數都是從右到左推進的(最右邊的參數是先推動的),但Pascal除外。

xtofl沒有涉及的另一個場景是寄存器參數 - 一些ABI要求某些參數在寄存器中,而不是在堆棧中的。在一個x86_64系統,例如,函數:

int add3(int a, int b, int c) 

會把參數:

a -> rdi 
b -> rsi 
c -> rdx 

具體而言,這看起來像(Intel語法):

mov  rdi, [source-of-a] 
mov  rsi, [source-of-b] 
mov  rdx, [source-of-c] 
call add3 

所以寄存器從註冊表中填入從左到右然後堆棧被使用從右到左

由於xtofl說,沒關係,你不提供什麼樣的主叫用戶和被叫同意 - 但是很顯然,如果主叫用戶和被叫反對這會導致不兼容的問題,其實這是一種不關注只適用於彙編程序,但也適用於更高級別的語言 - 幸運的是,編譯器很大程度上正確運行。爲了進一步閱讀,您可能會發現堆棧的被調用者/調用者清除有趣 - 並注意它是如何標準化爲x86_64的一種方法的。

你不會說你正在使用x86 - 你的架構肯定會有一個標準的調用約定,因爲沒有它的工作很困難。

+0

非常感謝你們倆。這非常有幫助,我現在明白它好多了!非常感謝! – Axolotl 2012-02-06 12:19:15