我一直在閱讀32位調用約定的差異。 fastcall
與stdcall
即是。64位快速調用
從我讀到的這兩個約定有很大的混淆,並且64位被標準化以避免這種混淆。
我不得不問,爲什麼選擇fastcall
?
此外,由於fastcall
和stdcall
是win32術語,函數調用的UNIX術語是否使用寄存器來傳遞參數?
我一直在閱讀32位調用約定的差異。 fastcall
與stdcall
即是。64位快速調用
從我讀到的這兩個約定有很大的混淆,並且64位被標準化以避免這種混淆。
我不得不問,爲什麼選擇fastcall
?
此外,由於fastcall
和stdcall
是win32術語,函數調用的UNIX術語是否使用寄存器來傳遞參數?
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
也不是,雖然都使用大量的寄存器來傳遞參數。
我更擔心BSD,因爲他們一直都有基於堆棧的調用,這既簡單又節省CPU時間,因爲您不需要事先備份寄存器。從我所瞭解的你所說的話看來,在64bit中不需要註冊通行證? – Hawken 2012-07-11 01:05:37
@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
即使是FreeBSD開發手冊也指出註冊傳遞速度較慢。我傾向於相信他們,因爲FreeBSD開發人員通常可以通過端口寄存器/堆棧傳遞程序進行測試,因爲他們經常移植Linux代碼。除此之外,你會認爲你需要將傳入的值寫入堆棧,因爲你將在你的指令中使用'%e_x'寄存器。除非你的功能只是調用另一個功能。 – Hawken 2012-07-12 08:39:10
它並不完全是快速調用,它是「我們有8個更多的寄存器,讓我們用'em'調用約定。 – 2012-07-11 00:23:19
@hansPassant實際上沒有使用寄存器來保存參數,因爲通常必須事先將寄存器備份到堆棧中。在非常特殊的情況下,快速調用只會更快。 – Hawken 2012-07-11 01:02:00
你假設他們必須「備份」。一般來說這不是一個正確的假設。代碼生成器可以將它們視爲暫存或從內存中重新加載它們。 「讓我們使用'em'計劃不是」讓我們全部使用'。 – 2012-07-11 01:07:23