2010-11-24 73 views
9

我一直在關注編程Ground Up的優秀書籍,想學習大會。雖然在這一點上沒有在本書中,但我想從C上的一個32位機器上調用我的彙編函數,這在從本書開始的工作中是一樣的。C到程序集調用約定32位和64位

我在這裏做的是存儲第一個參數%ebx和第二個%ecx

.type power, @function 
.globl power 
power: 
    pushq %ebp 
    movl %esp, %ebp 
    subl $4, %esp 

    movl 8(%ebp), %ebx 
    movl 12(%ebp), %ecx 

我編譯這個(和功能的其餘部分)到目標文件,創建一個main.c中,在那裏我原型的功能和調用它,像這樣:

int power(int b, int x); 
int a = power(2, 1); 

然而,當我在64位機器上編譯時,我得到了一些非常意想不到的結果。我修改了顯而易見的事實,例如%esp%epb需要用%rsp%rpb替代,但使用GDB進行挖掘顯示參數無法在堆棧中找到!

檢查通過使用-S選項GCC會發生什麼我可以看到,而不是推動堆棧上的變量,GCC將參數存儲在寄存器中。

movl $1, %esi 
movl $2, %edi 
call power 

在32位機,它做什麼,我期待並推棧上的參數:

movl $1, 4(%esp) 
movl $2, (%esp) 
call power 

現在是怎麼回事呢?爲什麼GCC通過64位寄存器和32位堆棧上的參數?這很混亂!我無法在任何地方找到任何提及。有沒有人可以在這種情況下啓發我?

+1

x64調用約定與x86不同。在大多數情況下,由於額外的寄存器,前四個參數被傳入寄存器。 – wj32 2010-11-24 11:02:26

回答

27

64位C調用約定是:%RDI,%RSI,%RDX,%RCX,%R 8和%R9

查看完整的描述在這裏: "System V Application Binary Interface: AMD64 Architecture Processor Supplement" http://www.x86-64.org/documentation/abi.pdf

3.2功能調用序列

當我學到相同的主題時,我製作了具有所需功能的小型C程序,將它們編譯爲64位編譯器並讀取由C編譯器生成的彙編代碼。 C/C++編譯器可以用於類似Assembly的引用。

+0

我瀏覽了那個確切的文檔,但我現在更仔細地研究了它,並且它在那裏,現在它完全有意義。謝謝! – Cbsch 2010-11-24 11:13:33