關於函數呼叫慣例的學習筆記

來源:互聯網
上載者:User

總體概述:

關於呼叫慣例中,主要涉及的內容就是不同的呼叫慣例對於函數調用棧平衡是由調用者維護棧平衡還是被調用者自己維護棧平衡、傳入參數的方向從右至左還是從左至右通過棧傳參還是通過寄存器傳參、還有一個就是關於不同呼叫慣例方式對於函數名的修飾方式。總體上瞭解這些就差不多了。

----------------------------------------------------------------------

調用者自己恢複棧平衡,用於可變參函數,呼叫慣例為__cdecl,彙編代碼錶現
push 參數
call 函數
add esp,4

被調用者自己恢複棧平衡__stdcall
push 參數
call 函數

採用寄存器傳參__fastcall
mov edx,參數
mov ecx,參數
call 函數

以上各種呼叫慣例對應的編譯器選項 /Gz (stdcall)、/Gr (fastcall)、/Gd (cdecl)

說明:在MSDN協助文檔中可以搜關鍵字__cdcel
----------------------------------------------------------------------
關於使用不同呼叫慣例的C函數名修飾:
C 函數的修飾形式取決於其聲明中使用的呼叫慣例,如下所示。

呼叫慣例              修飾
 
__cdecl(預設值)     前置底線 (_)
 
__stdcall             前置底線 (_) 和結尾 at 符 (@),後面跟表示參數列表中的位元組數的數字
 
__fastcall            與 __stdcall 相同,但前置符不是底線,而是 @ 符

執行個體分析:(自己動手實踐驗證VS2010)
函數原型:    修飾後的名稱:
int __fastcall fun3(int a, int b);   @fun3@8
int __stdcall fun2(int a, int b);   _fun2@8
int __cdecl fun1(int a, int b);   _fun1

------------------------C++ 修飾名的格式----------------------------------------------
C++ 函數的修飾名包含下列資訊:

函數名。

函數所屬的類(如果函數是成員函數)。這可能包括封裝函數的類的類,等等。

函數所屬的命名空間(如果函數是某個命名空間的組成部分)。

函數的參數類型。

呼叫慣例。

函數的傳回型別。

函數名和類名在修飾名中以代碼形式存在。修飾名的其餘部分是僅對編譯器和連結器具有內部意義的代碼。下面是未修飾的和修飾的 C++ 名稱的樣本。

未裝飾名稱 修飾名
 
int a(char){int i=3;return i;};        ?a@@YAHD@Z 
 
void __stdcall b::c(float){};          ?c@b@@AAGXM@Z 
 

------------Argument Passing and Naming Conventions---------------------------------
Microsoft Specific

All arguments are widened to 32 bits when they are passed. Return values are also widened to 32 bits and returned in the EAX register, except for 8-byte structures, which are returned in the EDX:EAX register pair. Larger structures are returned in the EAX register
as pointers to hidden return structures. Parameters are pushed onto the stack from right to left. Structures that are not PODs will not be returned in registers.

The compiler generates prolog and epilog code to save and restore the ESI, EDI, EBX, and EBP registers, if they are used in the function.

Note: 
When a struct, union, or class is returned from a function by value, all definitions of the type need to be the same, else the program may fail at runtime.
 

For information on how to define your own function prolog and epilog code, see (Naked Function Calls).

The following calling conventions are supported by the Visual C/C++ compiler.

Keyword Stack cleanupParameter passing
 
__cdecl CallerPushes parameters on the stack, in reverse order (right to left)
 
__clrcall n/a
Load parameters onto CLR expression stack in order (left to right).
 
__stdcall CalleePushes parameters on the stack, in reverse order (right to left)
 
__fastcall CalleeStored in registers, then pushed on stack
 

__thiscall CalleePushed on stack; this pointer stored in ECX

最後補充一點就是關於呼叫慣例在IPF處理器和X64處理器下的一些說明,以下引用自MSDN協助手冊中的原話:

On Itanium Processor Family (IPF) and x64 processors, __cdecl is accepted and ignored by the compiler; on IPF, by convention, parameters are passed in register. 

On Itanium Processor Family (IPF) and x64 processors, __stdcall is accepted and ignored by the compiler; on IPF, by convention, parameters are passed in register. 

On Itanium Processor Family (IPF) and AMD64 machines, __fastcall is accepted and ignored by the compiler; on an IPF chip, by convention, parameters are passed in register. 

主要說的就是在這兩種處理直接採用寄存器傳參方式。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.