函数调用约定
..
参数传递顺序
1.从右到左依次入栈:__stdcall,__cdecl,__thiscall,__fastcall
2.从左到右依次入栈:__pascal
主要说明__stdcall 和 __cdecl 区别
1…__stdcall 被调用的 函数本身负责堆栈平衡
2…__cdecl 调用函数 者负责 该函数的 堆栈平衡
///////********************** __stdcall 函数本身负责堆栈平衡 *********************////////////////
int __stdcall a(int v1,int xx)
{
return 5;
}
int main()
{
int t=a(5,1);
return 0;
}
/**/
--- c:\users\hekun\desktop\cppp\cppp\源.cpp -------------------------------------
int __stdcall a(int v1,int xx)
{
001713C0 push ebp
001713C1 mov ebp,esp
001713C3 sub esp,0C0h
001713C9 push ebx
001713CA push esi
001713CB push edi
001713CC lea edi,[ebp-0C0h]
001713D2 mov ecx,30h
001713D7 mov eax,0CCCCCCCCh
001713DC rep stos dword ptr es:[edi]
return 5;
001713DE mov eax,5
}
001713E3 pop edi
001713E4 pop esi
001713E5 pop ebx
001713E6 mov esp,ebp
001713E8 pop ebp
001713E9 ret 8 /*堆栈平衡 函数参数占用8字节*/
--- c:\users\hekun\desktop\cppp\cppp\源.cpp -------------------------------------
int main()
{
00171400 push ebp
00171401 mov ebp,esp
00171403 sub esp,0CCh
00171409 push ebx
0017140A push esi
0017140B push edi
0017140C lea edi,[ebp-0CCh]
00171412 mov ecx,33h
00171417 mov eax,0CCCCCCCCh
0017141C rep stos dword ptr es:[edi]
int t=a(5,1);
0017141E push 1
00171420 push 5
00171422 call a (01711E0h) /* 调用函数a*/
00171427 mov dword ptr [t],eax /*返回值位于寄存器eax*/
return 0;
0017142A xor eax,eax
}
0017142C pop edi
0017142D pop esi
0017142E pop ebx
0017142F add esp,0CCh
00171435 cmp ebp,esp
00171437 call __RTC_CheckEsp (017113Bh)
0017143C mov esp,ebp
0017143E pop ebp
0017143F ret
///////********************** __cdecl 调用函数者 负责堆栈平衡 *********************////////////////
int __cdecl a(int v1,int xx)
{
return 5;
}
int main()
{
int t=a(5,1);
return 0;
}
/*
反汇编
*/
--- c:\users\hekun\desktop\cppp\cppp\源.cpp -------------------------------------
int __cdecl a(int v1,int xx)
{
00F313C0 push ebp
00F313C1 mov ebp,esp
00F313C3 sub esp,0C0h
00F313C9 push ebx
00F313CA push esi
00F313CB push edi
00F313CC lea edi,[ebp-0C0h]
00F313D2 mov ecx,30h
00F313D7 mov eax,0CCCCCCCCh
00F313DC rep stos dword ptr es:[edi]
return 5;
00F313DE mov eax,5
}
00F313E3 pop edi
00F313E4 pop esi
00F313E5 pop ebx
00F313E6 mov esp,ebp
00F313E8 pop ebp
00F313E9 ret
--- c:\users\hekun\desktop\cppp\cppp\源.cpp -------------------------------------
int main()
{
00F31400 push ebp
00F31401 mov ebp,esp
00F31403 sub esp,0CCh
00F31409 push ebx
00F3140A push esi
00F3140B push edi
00F3140C lea edi,[ebp-0CCh]
00F31412 mov ecx,33h
00F31417 mov eax,0CCCCCCCCh
00F3141C rep stos dword ptr es:[edi]
int t=a(5,1);
00F3141E push 1
00F31420 push 5
00F31422 call a (0F311E5h) /* 调用函数 a */
00F31427 add esp,8 /* 由于是 __cdecl 调用方式 所以调用者 main 负责堆栈平衡,函数a 返回后 立即堆栈平衡(占用8字节) 变参函数只能是这种调用,因为只有调用者才知道 参数实际大小*/
00F3142A mov dword ptr [t],eax
return 0;
00F3142D xor eax,eax
}
00F3142F pop edi
00F31430 pop esi
00F31431 pop ebx
00F31432 add esp,0CCh
00F31438 cmp ebp,esp
00F3143A call __RTC_CheckEsp (0F3113Bh)
00F3143F mov esp,ebp
00F31441 pop ebp
00F31442 ret
__fastcall 调用 前参数 最大8字节 一次放入寄存器 ecx和edx 其余参数 放入栈中