函数堆栈调用
在了解函数堆栈调用之前我们先来看看这5个问题
- 形参是由谁开辟的?在哪里开辟?
形参是由调用方开辟的
- 形参的入栈顺序?
自右向左(支持可变参 从左至右不知道实参的个数大小 而自右向左 能跑到后面 证明已经知道了参数的个数)
- 函数的返回值由谁带出来?
由寄存器带出来
- 为什么回退到了调用方栈桢
- 怎么控制函数沿着函数调用点继续执行?
Call函数在调用之前 把下一行指令地址压栈了 当ret出栈时 把出栈的元素赋给了cpu的pc寄存器 pc寄存器放的cpu下一行指令的地址
定义一个函数void add(int a, int b),这里的a和b就是形参
当进行函数调用的时候add(1, 2),这里的1和2就是实参
一.函数堆栈调用过程如下:
- 开辟形参内存并初始化
- 压入下一行指令地址
- 压入调用方栈底指针的值
- 开辟局部变量所需要的栈空间并初始化
清栈过程刚好相反
二.函数非类类型(内置int char double 指针 结构体)返回值的返回方式:
- 0< <4字节:通过1个eax将返回值带出来
- 4< <=8字节:由eax,edx将返回值带出来
- >8字节:由临时量带回来
三.函数的调用约定
_cdecl C标准调用约定
_stdcall windows标准的调用约定
_fastcall 快速调用约定
_thiscall 类成员方法的调用约定
约定内容:
- 函数符号的生成
- 实参的入栈顺序(从右向左)
- 形参的开辟和清理方式
_cdecl:形参 由调用方开辟 调用方清理;
_stdcall:形参由调用方开辟,被调用方清理;
_fastcall:形参由 内置类型 <= 4 字节 前两个形参不开辟 由寄存器带入
其他情况 形参由调用方开辟 被调用方清理