__cdecl __fastcall與__stdcall,三者都是呼叫約定(Calling convention),它決定以下內容:1)函式引數的壓棧順序,2)由呼叫者還是被呼叫者把引數彈出棧,3)以及產生函式修飾名的方法。
1、__stdcall呼叫約定:函式的引數自右向左通過棧傳遞,被呼叫的函式在返回前清理傳送引數的記憶體棧。
2、_cdecl是C和C++程式的預設呼叫方式。每一個呼叫它的函式都包含清空堆疊的程式碼,所以產生的可執行檔案大小會比呼叫_stdcall函式的大。函式採用從右到左的壓棧方式。注意:對於可變引數的成員函式,始終使用__cdecl的轉換方式。
3、__fastcall呼叫約定:它是通過暫存器來傳送引數的(實際上,它用ECX和EDX傳送前兩個雙字(DWORD)或更小的引數,剩下的引數仍舊自右向左壓棧傳送,被呼叫的函式在返回前清理傳送引數的記憶體棧)。
5、nakedcall採用1-4的呼叫約定時,如果必要的話,進入函式時編譯器會產生程式碼來儲存ESI,EDI,EBX,EBP暫存器,退出函式時則產生程式碼恢復這些暫存器的內容。naked call不產生這樣的程式碼。naked call不是型別修飾符,故必須和_declspec共同使用。
cdecl 是 C 語言的呼叫方式,函式引數從右到左求值,然後入棧,引數由呼叫方負責清理,傳多少引數其實都無所謂的,於是就支援所謂的可變長度的引數;
stdcall 是 C++ 的呼叫方式,引數從右到左求值,入棧,由被呼叫方處理引數,所以引數個數型別都必須匹配;
pascal 是對 PASCAL 函式的呼叫方式,引數自左向右求值,其他類似於 stdcall;
而 fastcall 的情況忽略。