函数调用约定

梦想游戏人
目录:
汇编

..

参数传递顺序

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  其余参数 放入栈中

Scroll Up