调用约定 | 参数压栈顺序 | 平衡堆栈 |
__cdecl | 从右至左入栈 | 调用者清理栈 |
__stdcall | 从右至左入栈 | 自身清理堆栈 |
__fastcall | ECX/EDX传送前两个,剩下:从右至左入栈 | 自身清理堆栈 |
1.__cdecl C、C++默认的调用约定
#include "stdafx.h"
int __cdecl Plus1(int x, int y){
return x+y;
}
int main(int argc, char* argv[])
{
Plus1(1,2);
return 0;
}
17: int main(int argc, char* argv[])
18: {
004010D0 push ebp
004010D1 mov ebp,esp
004010D3 sub esp,40h
004010D6 push ebx
004010D7 push esi
004010D8 push edi
004010D9 lea edi,[ebp-40h]
004010DC mov ecx,10h
004010E1 mov eax,0CCCCCCCCh
004010E6 rep stos dword ptr [edi]
19: Plus1(1,2);
004010E8 push 2
004010EA push 1
004010EC call @ILT+10(Plus1) (0040100f)
004010F1 add esp,8 //__cdecl 从右至左入栈 ,调用者清理栈
20: return 0;
004010F4 xor eax,eax
21: }
004010F6 pop edi
004010F7 pop esi
004010F8 pop ebx
004010F9 add esp,40h
004010FC cmp ebp,esp
004010FE call __chkesp (00401120)
00401103 mov esp,ebp
00401105 pop ebp
00401106 ret
2、__stdcall windows api 内平栈
int __stdcall Plus2(int x, int y){
return x+y;
}
int main(int argc, char* argv[])
{
Plus2(1,2);
return 0;
}
19: Plus2(1,2);
004010E8 push 2
004010EA push 1
004010EC call @ILT+5(Plus2) (0040100a) //__stdcall 从右至左入栈 自身清理堆栈
20: return 0;
004010F1 xor eax,eax
…………
11: return x+y;
00401078 mov eax,dword ptr [ebp+8]
0040107B add eax,dword ptr [ebp+0Ch]
12: }
0040107E pop edi
0040107F pop esi
00401080 pop ebx
00401081 mov esp,ebp
00401083 pop ebp
00401084 ret 8 //__stdcall 自身清理堆栈
3、__fastcall 速度快
19: Plus3(1,2);
004010E8 mov edx,2
004010ED mov ecx,1
004010F2 call @ILT+0(Plus3) (00401005) //ECX/EDX传送前两个,剩下:从右至左入栈
int __fastcall Plus3(int x, int y, int z,int k){
return x+y;
}
int main(int argc, char* argv[])
{
Plus3(1,2,3,4);
return 0;
}
Plus3(1,2,3,4);
004010E8 push 4
004010EA push 3
004010EC mov edx,2
004010F1 mov ecx,1 //ECX/EDX传送前两个,剩下:从右至左入栈
004010F6 call @ILT+20(Plus3) (00401019)
…………………………
15: return x+y;
004010B0 mov eax,dword ptr [ebp-4]
004010B3 add eax,dword ptr [ebp-8]
16: }
004010B6 pop edi
004010B7 pop esi
004010B8 pop ebx
004010B9 mov esp,ebp
004010BB pop ebp
004010BC ret 8