__stdcall、__cdcel和__fastcall定義與區別
阿新 • • 發佈:2021-01-30
技術標籤:C++
__stdcall
- 被這個關鍵字修飾的函式,其引數都是從右向左通過堆疊傳遞的(__fastcall 的前面部分由ecx,edx傳), 函式呼叫在返回前要由被呼叫者清理堆疊。
這個關鍵字主要見於Microsoft Visual C、C++。GNU的C、C++是另外一種修飾方式:attribute((stdcall))
__cdecl
- __cdecl 是C Declaration的縮寫(declaration,宣告),表示C語言預設的函式呼叫方法:所有引數從右到左依次入棧,這些引數由呼叫者清除,稱為手動清棧。被呼叫函式不會要求呼叫者傳遞多少引數,呼叫者傳遞過多或者過少的引數,甚至完全不同的引數都不會產生編譯階段的錯誤。
__fastcall
- __fastcall 是一種快速呼叫方式。
呼叫約定(Calling Convention)
規定將前兩個引數由暫存器ecx和edx來傳遞,其餘引數還是通過堆疊傳遞(從右到左)。
不同編譯器編譯的程式規定的暫存器不同。在Intel 386平臺上,使用ECX和EDX暫存器。
使用__fastcall方式無法用作跨編譯器的介面。
可參考GCC說明文件。
簡單的例子
#include<stdio.h>
int __stdcall func1(int a, int b){
printf("a = %d, b = %d\n", a, b);
return a+b;
}
int __cdecl func2(int a, int b){
printf("a = %d, b = %d\n", a, b);
return a+b;
}
int __fastcall func3(int a, int b){
printf("a = %d, b = %d\n", a, b);
return a+b;
}
int main(int argc, char const *argv[])
{
int v1 = 2;
printf("%d\n", func1(v1++, v1));
int v2 = 2;
printf("%d\n", func2(v2, v2++));
int v3 = 2;
printf("%d\n", func3(v3++, v3));
return 0;
}