1、函数调用在汇编中,有关于参数传递与栈平衡的问题,可参照函数调用在汇编中的基本实现,主要有三种方式__cdecl、__stdcall、__fastcall;
2、在C++代码中,可以在函数名前加这三个关键字来设定编译方式,先上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // VCTest.cpp : Defines the entry point for the console application. // #include "stdafx.h" int __cdecl sum1(int a, int b) { return a + b; } int __stdcall sum2(int a, int b) { return a + b; } int __fastcall sum3(int a, int b) { return a + b; } int main(int argc, char* argv[]) { sum1(2, 3); sum2(2, 3); sum3(2, 3); return 0; } |
3、断点反汇编
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 20: sum1(2, 3); ;参数从右至左传递,外平栈,修改esp值 0040D7A8 push 3 0040D7AA push 2 0040D7AC call @ILT+20(print) (00401019) 0040D7B1 add esp,8 21: sum2(2, 3); ;参数从右至左传递,内平栈,后面再贴出函数内部实现 0040D7B4 push 3 0040D7B6 push 2 0040D7B8 call @ILT+30(sum2) (00401023) 22: sum3(2, 3); ;参数从右至左,直接使用寄存器,不需要平栈 0040D7BD mov edx,3 0040D7C2 mov ecx,2 0040D7C7 call @ILT+25(sum3) (0040101e) |
3.1、__stdcall sum3()内部反汇编,最后一句ret 8
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 10: int __stdcall sum2(int a, int b) 11: { 00401050 push ebp 00401051 mov ebp,esp 00401053 sub esp,40h 00401056 push ebx 00401057 push esi 00401058 push edi 00401059 lea edi,[ebp-40h] 0040105C mov ecx,10h 00401061 mov eax,0CCCCCCCCh 00401066 rep stos dword ptr [edi] 12: return a + b; 00401068 mov eax,dword ptr [ebp+8] 0040106B add eax,dword ptr [ebp+0Ch] 13: } 0040106E pop edi 0040106F pop esi 00401070 pop ebx 00401071 mov esp,ebp 00401073 pop ebp 00401074 ret 8 ;内平栈! |