一、C++中函数的调用方式主要有以下三种:
1._cdecl:是c++中默认的调用方式,所用参数从右到左入栈,这些参数由调用者清除
2._stdcall:入栈方向一致,参数由被调用者清除
3._fastcall:是快速调用方式,一般是前两个参数由寄存器传递,其他参数还是用栈传递,参数由被调用者清除
这里的东西比较简单,其实就是add esp,xxxx 是放到被调用函数内部还是放在调用语句之后的区别
如果你有时在call之后看到add esp,xxxx就知道是消除参数用的了
二、被调函数****(参数及返回值和局部变量的存放位置)栈帧形成****
1----函数 调用 入口会遇到这三行代码(如下)
push ebp ;
mov ebp ,esp ;
sub esp,xxx;
其实就是用来形成栈帧的(如下图)
这个栈帧(地址)用于存放被调函数的信息,包括在被调用函数内部声明的局部变量。这个在真正开始调用函数时才开始形成的,而参数却是在栈帧形成前就已经被压入栈中了。
其实,[EBP]中存放的应该是栈帧生成前的EBP的值,因为被调函数的开始有个push ebp。而[EBP+4]中存放的应该是函数的返回地址,因为调用函数时压入参数之后还会把下一条语句的地址压入栈中。
2-----参数和局部变量的使用
mov ecx,ss:[ebp+0x08]; 参数获取 //当内存中括号中包含ESP或者EBP的话 用SS
mov ecx,ss:[esp+0x0C]; 局部变量获取
mov eax,dword ptr ds:[edx+0x13C];//当内存中括号中包含EAX或者EDX的话 用DS
3-----函数返回-----
MOV ESP,EBP;
POP EBP ; //恢复堆栈
RETN