x86 msvc编译下 函数调用约定
void __stdcall ShowStd(int a, int b, int c, int d) { printf("%d %d %d %d ", a, b, c, d); } void __cdecl ShowCde(int a, int b, int c, int d) { printf("%d %d %d %d ", a, b, c, d); } void __fastcall ShowFast(int nOne, int nTwo, int nThree, int nFour) { printf("%d %d %d %d ", nOne, nTwo, nThree, nFour); }
108: ShowCde(1, 2, 3, 4); //__cdecl 调用,参数从右向左入栈,调用者平衡栈,(不定参数函数使用cdcel) 000E845E 6A 04 push 4 000E8460 6A 03 push 3 000E8462 6A 02 push 2 000E8464 6A 01 push 1 000E8466 E8 7F B0 FF FF call ShowCde (0E34EAh) 000E846B 83 C4 10 add esp,10h //平衡栈 109: ShowStd(1, 2, 3, 4); //__stdcall,参数从右向左入栈,被调用者平衡栈(即函数内取消参数空间) 000E846E 6A 04 push 4 000E8470 6A 03 push 3 000E8472 6A 02 push 2 000E8474 6A 01 push 1 000E8476 E8 92 A1 FF FF call ShowStd (0E260Dh) 110: ShowFast(1, 2, 3, 4); //__fastcall,参数1使用ecx,参数2使用edx,其他参数入栈,自右向左。被调用者平衡栈 000E847B 6A 04 push 4 000E847D 6A 03 push 3 000E847F BA 02 00 00 00 mov edx,2 000E8484 B9 01 00 00 00 mov ecx,1 000E8489 E8 D1 C2 FF FF call ShowFast (0E475Fh) //函数内会将edx和ecx中的值保存到临时变量
调用规则 |
入栈顺序 |
平衡栈者 |
__cdecl |
从右到左 |
调用者 |
__stdcall |
从右到左 |
被调用者 |
__fastcall |
从右到左(参数1EDX、参数2ECX,其他参数使用堆栈) |
被调用者 |
PASCAL |
从左到右 |
被调用者 |
x64 下: