函数调用方式
2021-07-01
236
0
Stdcall (WINAPI)
1.windows api的调用方式。
2.参数由右到左入栈,由被调用者进行栈清理。
Thiscall
1.C++类成员函数缺省的调用约定。
2.参数从右向左入栈;
3.如果参数个数确定,this指针通过ecx传递给被调用者;如果参数个数不确定this指针在所有参数压栈后被压入栈;
4.对参数个数不定的,调用者清理栈,否则函数自己清理栈。
Cdecl
1.C调用约定,是C语言缺省的调用约定
2.参数从右向左压入堆栈。
3.调用者负表平衡栈空间。
4.允许参数个数不定。
Fastcall
X86:
1.规定将前两个(或若干个)参数由寄存器传递,其余参数还是通过栈传递(从右到左)。
2.不同编译器编译的程序规定的寄存器不同。在Intel 386平台上,使用ECX和EDX寄存器,故使用__fastcall方式无法用作跨编译器的接口。
X64:
1.x64下的调用方式,参数从右向左传入。
2.函数参数的前4个寄存器分别为rcx,rdx,r8,r9。前四个浮点类型参数由XMM0,XMM1,XMM2,XMM3依次传递。
3.由调用函数负责清理调用栈
4.浮点返回值由XMM0传递。
5.虽然前4个数据由寄存器传入,但系统会为其留栈空间
如下函数C语言采用不同的调用方式
int fun(char a,char b)
{
int x = a;
int y = b;
return x+y;
}
void main()
{
int k = fun(1,2);
}
stdcall调用方式
int k = fun(1,2);
00CF13EE push 2
00CF13F0 push 1
00CF13F2 call fun (0CF11C2h)
00CF13F7 mov dword ptr [k],eax
cdecl调用方式
int k = fun(1,2);
00CF13EE push 2
00CF13F0 push 1
00CF13F2 call fun (0CF11C2h)
00CF13F7 mov dword ptr [k],eax
cdecl调用方式
int k = fun(1,2);
003E13EE push 2
003E13F0 push 1
003E13F2 call fun (3E11BDh)
003E13F7 add esp,8
003E13FA mov dword ptr [k],eax
fastcall调用方式
int k = fun(1,2);
008313EE mov dl,2
008313F0 mov cl,1
008313F2 call fun (8311C7h)
008313F7 mov dword ptr [k],eax
三、函数的栈帧
函数的栈帧是当前函数的运行时空间,只对当前函数内有效。
函数的栈帧包括参数,函数返回地址,栈桢基址和函数内部的临时变量。
对于如下函数,fun的函数栈桢如下图所示:
int fun(int a,int b)
{
int x = a+1;
int y = b+2;
return x+y;
}
void main()
{
int k = fun(1,2);
printf("%d",k);
}
反汇编如下:
text:00411380 sub_411380 proc near ; CODE XREF: .text:004111BDj
.text:00411380 ; .text:004111C2j ...
.text:00411380
.text:00411380 var_D8 = byte ptr -0D8h
.text:00411380 var_14 = dword ptr -14h
.text:00411380 var_8 = dword ptr -8
.text:00411380 arg_0 = dword ptr 8
.text:00411380 arg_4 = dword ptr 0Ch
.text:00411380
.text:00411380 push ebp
.text:00411381 mov ebp, esp
.text:00411383 sub esp, 0D8h
.text:00411389 push ebx
.text:0041138A push esi
.text:0041138B push edi
.text:0041138C lea edi, [ebp+var_D8]
.text:00411392 mov ecx, 36h
.text:00411397 mov eax, 0CCCCCCCCh
.text:0041139C rep stosd
.text:0041139E mov eax, [ebp+arg_0]
.text:004113A1 add eax, 1
.text:004113A4 mov [ebp+var_8], eax
.text:004113A7 mov eax, [ebp+arg_4]
.text:004113AA add eax, 2
.text:004113AD mov [ebp+var_14], eax
.text:004113B0 mov eax, [ebp+var_8]
.text:004113B3 add eax, [ebp+var_14]
.text:004113B6 pop edi
.text:004113B7 pop esi
.text:004113B8 pop ebx
.text:004113B9 mov esp, ebp
.text:004113BB pop ebp
.text:004113BC retn
.text:004113BC sub_411380 endp