函数的调用过程:(带括号的是非主函数被调用时的调用过程)
(0.形参的初始化。)
(0.1压入下一行指令地址)
1.开辟主函数栈帧空间并初始化
2.压入调用方栈底指针寄存器的值
3.移动ebp到被调用方栈底
4.移动esp到栈顶
5.为了保留3个寄存器的值,把寄存器的值先压入(修改了也不怕了,反正可以找回)
6.开辟局部变量活动需要的栈空间并初始化为cccccccc
函数的退栈过程刚好相反。
调用约定:
1.__cdecl c标准调用约定
2.__stdcall windows标准调用约定
3.__fastcall 快速调用约定
4.__thiscall 成员方法的调用约定
返回值的返回方式
1.返回值小于等于4个字节->通过eax寄存器带回
2.4<返回值<8 个字节,通过eax和ebx寄存器带回
3.返回值大于8个字节,在调用方栈空间开辟临时量,返回值直接写入临时量中。
对于此种情况,在函数调用过程中需要加一步:在形参初始化后还要压入临时量的地址。
1、符号的生成:
不同的调用约定,符号的生成规则不同,如果显示调用不同的调用约定,则会链接时报符号无法解析的错误。
2、入栈顺序:
c/c++体系都是从右向左
3、形参内存的开辟和清理:
_cdecl:
开辟:调用方
清理:调用方
_stdcall:
开辟: 调用方
清理: 被调用方
_fastcall:
前两个形参时由寄存器带入被调用方,没有内存开辟
以后的形参都是和_stdcall的调用约定形式相同。