-
-
第五天函数调用堆栈情况
-
发表于: 2021-4-6 03:21 2452
-
所有语言平台 的内存结构都分4个区
代码区
数据区 数据区分 已初始化区和 未初始化区(可读可写)
栈区
堆区
write可读
read可写
execute可执行
share可分享
调用约定:
调用约定
1.参数的传递方向
2.参数的存储媒介
3.谁负责释放参数空间
4.返回值的处理**
cdecall:(国标约定)
从右往左传参,参数通过堆栈传参,由调用方负责清理参数空间(支持不定参)
stdcall:(微软约定)
从右往左传参,参数通过堆栈传参,由被调用方负责清理参数空间(不支持不定参)
__fastcall:(不能跨平台)
从右往左传参, 左数前前两个参数使用寄存器传参(ECX EDX),其余通过堆栈传参,被掉方负责清理空间(不支持不定参)
thiscall:(c++)
对象传递首地址。
函数调用的过程:
1.按调用约定传参。
2.在栈顶保存返回地址保存返回地址。
3.保存调用方的栈信息。
4.更新栈位置到被调方的栈底处。
5.在被调方栈内开辟局部变量的空间(debug 分配大于等于变量空间总和 优化版 分配小于等于变量空间总和)
编译器优化:( 1.int a = 3 ,printf("%d",a) 直接 printf(3) 2.把变量做成寄存器变量 3. A B 两个区域
分别有 x y两个变量 。x只在A中使用,y只在B中使用。那么生成1个变量就行,A中当x用,B中当y用)
*5A(不一定)编译选项有/ZI+/OD,则填充局部变量空间为0xcc。
6.保存寄存器环境
7.执行函数体
8.回复寄存器环境
9.释放局部变量空间
10.恢复栈信息位置到调用方
11.**取出返回地址返回地址,并按此作流程更新。抵达新地址后
,由调用方清理参数。(__cdel 外平栈)。由被调方清理参数(stdcall 内平栈)。
main函数有个特点,第二个参数是命令行参数,如果目标位置是个指针,且是
我们命令行的,实锤是main函数。
**