2012-07-10 93 views
2

我一直在閱讀32位調用約定的差異。 fastcallstdcall即是。64位快速調用

從我讀到的這兩個約定有很大的混淆,並且64位被標準化以避免這種混淆。

我不得不問,爲什麼選擇fastcall

此外,由於fastcallstdcall是win32術語,函數調用的UNIX術語是否使用寄存器來傳遞參數?

+0

它並不完全是快速調用,它是「我們有8個更多的寄存器,讓我們用'em'調用約定。 – 2012-07-11 00:23:19

+0

@hansPassant實際上沒有使用寄存器來保存參數,因爲通常必須事先將寄存器備份到堆棧中。在非常特殊的情況下,快速調用只會更快。 – Hawken 2012-07-11 01:02:00

+0

你假設他們必須「備份」。一般來說這不是一個正確的假設。代碼生成器可以將它們視爲暫存或從內存中重新加載它們。 「讓我們使用'em'計劃不是」讓我們全部使用'。 – 2012-07-11 01:07:23

回答

2

x86 Calling Conventions - Wikipedia, the free encyclopedia提供了一個列表。

x86-32上的通用調用約定是cdecl。 GCC提供了一個函數屬性__attribute__((regparm(n)))來指示n參數是通過寄存器傳遞的,但這不同於fastcall。無論哪種方式,參數都在callee-clobberable寄存器中傳遞,因此函數調用相對於cdecl(對於regparm)和stdcall(對於fastcall)沒有額外的開銷(並節省了爲參數添加堆棧空間的努力) 。

爲了幫助您解決混淆問題,Windows和Linux上的x86-64調用約定與x86-32和x86-32上的調用約定不同。 fastcall也不是,雖然都使用大量的寄存器來傳遞參數。

+0

我更擔心BSD,因爲他們一直都有基於堆棧的調用,這既簡單又節省CPU時間,因爲您不需要事先備份寄存器。從我所瞭解的你所說的話看來,在64bit中不需要註冊通行證? – Hawken 2012-07-11 01:05:37

+0

@Hawken:'regparm'和'fastcall'使用被調用者被破壞的寄存器,因此即使在'cdecl'和'stdcall'下也需要調用者保存 - 哪些CPU時間會丟失?目前C編譯器沒有使用非默認的x86-64調用約定。您可以看到[System V Application Binary Interface \ AMD64 Architecture Processor Supplement](http://www.x86-64.org/documentation/abi.pdf)和[MSDN | x64調用約定概述](http://msdn.microsoft.com/zh-cn/library/ms235286.aspx)瞭解當前正在使用的內容。 – ephemient 2012-07-11 01:17:14

+0

即使是FreeBSD開發手冊也指出註冊傳遞速度較慢。我傾向於相信他們,因爲FreeBSD開發人員通常可以通過端口寄存器/堆棧傳遞程序進行測試,因爲他們經常移植Linux代碼。除此之外,你會認爲你需要將傳入的值寫入堆棧,因爲你將在你的指令中使用'%e_x'寄存器。除非你的功能只是調用另一個功能。 – Hawken 2012-07-12 08:39:10