C++函数调用方式约定stdcall,cdecl,pascal,naked,thiscall,fastcall
https://www.cnblogs.com/xiangtingshen/p/11014514.html
C++函数调用约定
_cdecl约定:
参数:从右向左依次入栈
堆栈平衡:调用方平衡
#include "pch.h" #include <iostream> int __cdecl getMaxNumber(int a, int b, int c) { int temp = a > b ? a : b; return temp > c ? temp : c; } int main() { int iMax = 0; iMax = getMaxNumber(10, 30, 16); printf("iMAx = %d\n", iMax); }
.text:00411980 sub_411980 proc near ; CODE XREF: sub_4112B7↑j .text:00411980 .text:00411980 var_CC = byte ptr -0CCh .text:00411980 var_8 = dword ptr -8 .text:00411980 .text:00411980 push ebp .text:00411981 mov ebp, esp .text:00411983 sub esp, 0CCh .text:00411989 push ebx .text:0041198A push esi .text:0041198B push edi .text:0041198C lea edi, [ebp+var_CC] .text:00411992 mov ecx, 33h .text:00411997 mov eax, 0CCCCCCCCh .text:0041199C rep stosd .text:0041199E mov ecx, offset unk_41C009 .text:004119A3 call sub_411221 .text:004119A8 mov [ebp+var_8], 0 .text:004119AF push 16 // 从右到左入栈 .text:004119B1 push 30 .text:004119B3 push 10 .text:004119B5 call sub_411087 .text:004119BA add esp, 0Ch // 平衡堆栈 .text:004119BD mov [ebp+var_8], eax .text:004119C0 mov eax, [ebp+var_8] .text:004119C3 push eax .text:004119C4 push offset aImaxD ; "iMAx = %d\n" .text:004119C9 call sub_41104B .text:004119CE add esp, 8 .text:004119D1 xor eax, eax .text:004119D3 pop edi .text:004119D4 pop esi .text:004119D5 pop ebx .text:004119D6 add esp, 0CCh .text:004119DC cmp ebp, esp .text:004119DE call sub_41122B .text:004119E3 mov esp, ebp .text:004119E5 pop ebp .text:004119E6 retn .text:004119E6 sub_411980 endp
函数内部
push 参数一 //参数入栈顺序:从右向左依次入栈
push 参数二
push 。。。
push 参数N
call Fun //调用函数
add esp,XX //堆栈平衡
_stdcall约定:
参数:从右向左依次入栈
堆栈平衡:被调用方自己平衡
#include "pch.h" #include <iostream> int __stdcall getMaxNumber(int a, int b, int c) { int temp = a > b ? a : b; return temp > c ? temp : c; } int main() { int iMax = 0; iMax = getMaxNumber(10, 30, 16); printf("iMAx = %d\n", iMax); }
.text:004119A8 mov [ebp+var_8], 0 .text:004119AF push 16 .text:004119B1 push 30 .text:004119B3 push 10 .text:004119B5 call sub_411393 .text:004119BA mov [ebp+var_8], eax .text:004119BD mov eax, [ebp+var_8] .text:004119C0 push eax .text:004119C1 push offset aImaxD ; "iMAx = %d\n" .text:004119C6 call sub_41104B // 在函数内部恢复堆栈 .text:004119CB add esp, 8 .text:004119CE xor eax, eax .text:004119D0 pop edi .text:004119D1 pop esi .text:004119D2 pop ebx .text:004119D3 add esp, 0CCh .text:004119D9 cmp ebp, esp .text:004119DB call sub_41122B .text:004119E0 mov esp, ebp .text:004119E2 pop ebp .text:004119E3 retn .text:004119E3 sub_411980 endp
函数
text:004117D0 var_D0 = dword ptr -0D0h .text:004117D0 var_8 = dword ptr -8 .text:004117D0 arg_0 = dword ptr 8 .text:004117D0 arg_4 = dword ptr 0Ch .text:004117D0 arg_8 = dword ptr 10h .text:004117D0 .text:004117D0 push ebp .text:004117D1 mov ebp, esp .text:004117D3 sub esp, 0D0h .text:004117D9 push ebx .text:004117DA push esi .text:004117DB push edi .text:004117DC lea edi, [ebp+var_D0] .text:004117E2 mov ecx, 34h .text:004117E7 mov eax, 0CCCCCCCCh .text:004117EC rep stosd .text:004117EE mov ecx, offset unk_41C009 .text:004117F3 call sub_411221 .text:004117F8 mov eax, [ebp+arg_0] .text:004117FB cmp eax, [ebp+arg_4] .text:004117FE jle short loc_41180B .text:00411800 mov ecx, [ebp+arg_0] .text:00411803 mov [ebp+var_D0], ecx .text:00411809 jmp short loc_411814 .text:0041180B ; --------------------------------------------------------------------------- .text:0041180B .text:0041180B loc_41180B: ; CODE XREF: sub_4117D0+2E↑j .text:0041180B mov edx, [ebp+arg_4] .text:0041180E mov [ebp+var_D0], edx .text:00411814 .text:00411814 loc_411814: ; CODE XREF: sub_4117D0+39↑j .text:00411814 mov eax, [ebp+var_D0] .text:0041181A mov [ebp+var_8], eax .text:0041181D mov eax, [ebp+var_8] .text:00411820 cmp eax, [ebp+arg_8] .text:00411823 jle short loc_411830 .text:00411825 mov ecx, [ebp+var_8] .text:00411828 mov [ebp+var_D0], ecx .text:0041182E jmp short loc_411839 .text:00411830 ; --------------------------------------------------------------------------- .text:00411830 .text:00411830 loc_411830: ; CODE XREF: sub_4117D0+53↑j .text:00411830 mov edx, [ebp+arg_8] .text:00411833 mov [ebp+var_D0], edx .text:00411839 .text:00411839 loc_411839: ; CODE XREF: sub_4117D0+5E↑j .text:00411839 mov eax, [ebp+var_D0] .text:0041183F pop edi .text:00411840 pop esi .text:00411841 pop ebx .text:00411842 add esp, 0D0h .text:00411848 cmp ebp, esp .text:0041184A call sub_41122B .text:0041184F mov esp, ebp .text:00411851 pop ebp .text:00411852 retn 0Ch // 恢复堆栈 .text:00411852 sub_4117D0 endp .text:00411852
push 参数一 //参数入栈顺序:从右向左依次入栈
push 参数二
push 。。。
push 参数N
call Fun //调用函数,在函数内进行堆栈平衡,retn XX
_fastcall约定:
参数:从右向左依次入栈,当参数不大于二的时候一般把参数放到edx,ecx里面,大于二的时候参数放在堆栈里面
堆栈平衡:被调用方自己平衡
.text:00411980 var_CC = byte ptr -0CCh .text:00411980 var_8 = dword ptr -8 .text:00411980 .text:00411980 push ebp .text:00411981 mov ebp, esp .text:00411983 sub esp, 0CCh .text:00411989 push ebx .text:0041198A push esi .text:0041198B push edi .text:0041198C lea edi, [ebp+var_CC] .text:00411992 mov ecx, 33h .text:00411997 mov eax, 0CCCCCCCCh .text:0041199C rep stosd .text:0041199E mov ecx, offset unk_41C009 .text:004119A3 call sub_411221 .text:004119A8 mov [ebp+var_8], 0 .text:004119AF push 16 .text:004119B1 mov edx, 30 .text:004119B6 mov ecx, 10 .text:004119BB call sub_411398 .text:004119C0 mov [ebp+var_8], eax .text:004119C3 mov eax, [ebp+var_8] .text:004119C6 push eax .text:004119C7 push offset aImaxD ; "iMAx = %d\n" .text:004119CC call sub_41104B .text:004119D1 add esp, 8 .text:004119D4 xor eax, eax .text:004119D6 pop edi .text:004119D7 pop esi .text:004119D8 pop ebx .text:004119D9 add esp, 0CCh .text:004119DF cmp ebp, esp .text:004119E1 call sub_41122B .text:004119E6 mov esp, ebp .text:004119E8 pop ebp .text:004119E9 retn .text:004119E9 sub_411980 endp
函数内部
text:004117D0 sub_4117D0 proc near ; CODE XREF: .text:00411087↑j .text:004117D0 ; .text:00411393↑j ... .text:004117D0 .text:004117D0 var_E8 = dword ptr -0E8h .text:004117D0 var_20 = dword ptr -20h .text:004117D0 var_14 = dword ptr -14h .text:004117D0 var_8 = dword ptr -8 .text:004117D0 arg_0 = dword ptr 8 .text:004117D0 .text:004117D0 push ebp .text:004117D1 mov ebp, esp .text:004117D3 sub esp, 0E8h .text:004117D9 push ebx .text:004117DA push esi .text:004117DB push edi .text:004117DC push ecx .text:004117DD lea edi, [ebp+var_E8] .text:004117E3 mov ecx, 3Ah .text:004117E8 mov eax, 0CCCCCCCCh .text:004117ED rep stosd .text:004117EF pop ecx .text:004117F0 mov [ebp+var_14], edx .text:004117F3 mov [ebp+var_8], ecx .text:004117F6 mov ecx, offset unk_41C009 .text:004117FB call sub_411221 .text:00411800 mov eax, [ebp+var_8] .text:00411803 cmp eax, [ebp+var_14] .text:00411806 jle short loc_411813 .text:00411808 mov ecx, [ebp+var_8] .text:0041180B mov [ebp+var_E8], ecx .text:00411811 jmp short loc_41181C .text:00411813 ; --------------------------------------------------------------------------- .text:00411813 .text:00411813 loc_411813: ; CODE XREF: sub_4117D0+36↑j .text:00411813 mov edx, [ebp+var_14] .text:00411816 mov [ebp+var_E8], edx .text:0041181C .text:0041181C loc_41181C: ; CODE XREF: sub_4117D0+41↑j .text:0041181C mov eax, [ebp+var_E8] .text:00411822 mov [ebp+var_20], eax .text:00411825 mov eax, [ebp+var_20] .text:00411828 cmp eax, [ebp+arg_0] .text:0041182B jle short loc_411838 .text:0041182D mov ecx, [ebp+var_20] .text:00411830 mov [ebp+var_E8], ecx .text:00411836 jmp short loc_411841 .text:00411838 ; --------------------------------------------------------------------------- .text:00411838 .text:00411838 loc_411838: ; CODE XREF: sub_4117D0+5B↑j .text:00411838 mov edx, [ebp+arg_0] .text:0041183B mov [ebp+var_E8], edx .text:00411841 .text:00411841 loc_411841: ; CODE XREF: sub_4117D0+66↑j .text:00411841 mov eax, [ebp+var_E8] .text:00411847 pop edi .text:00411848 pop esi .text:00411849 pop ebx .text:0041184A add esp, 0E8h .text:00411850 cmp ebp, esp .text:00411852 call sub_41122B .text:00411857 mov esp, ebp .text:00411859 pop ebp .text:0041185A retn 4 .text:0041185A sub_4117D0 endp
push 参数一 //参数入栈顺序:从右向左依次入栈
push 参数二
push 。。。
push edx
push ecx //寄存器传递
call Fun //调用函数,在函数内进行堆栈平衡,retn XX
naked约定:
参数:从右向左依次入栈
堆栈平衡:调用方平衡
push 参数一 //参数入栈顺序:从右向左依次入栈
push 参数二
push 。。。
push 参数N
call Fun //调用函数
add esp,XX //堆栈平衡