函数栈帧的创建和销毁

函数栈帧的创建和销毁


1.寄存器的认知

函数栈帧的创建和销毁离不开寄存器,了解函数栈帧之前先了解一下cpu中的寄存器

cpu中供应用程序员使用的寄存器主要有:通用寄存器(EAX、EBX、ECX、EDX、ESP、EBP、ESI、EDI),段寄存器(CS、DS、SS、ES、FS、GS),标志和控制寄存器(EIP、EFLAGS)

其中EBP一般用作基址指针,ESP一般用作堆栈指针ebp作为栈底指针,esp作为栈顶指针

请添加图片描述

对于内存的认知:栈区、堆区、全局静态区、常量区、代码区 —实际存储是从高地址往低地址方向存储这也说明了为什么int a=0x11223344在查看内存监视器的时候,地址内容显示是44 33 22 11

请添加图片描述

请添加图片描述

对于esp和ebp的认知:

请添加图片描述

举例代码:

#include <stdio.h>
int ADD(int x, int y) {
	int z = 0;
	z = x + y;
	return z;
}
int main() {
	int a = 10;
	int b = 20;
	int c = 0;
	c = ADD(a, b);
	printf("%d", c);
	return 0;
}

通过反汇编有了如下图的结果:

请添加图片描述


2.栈帧的创建

通过上面的举例代码,我们剖析这个栈帧创建过程:首先是main函数创建栈帧,然后是ADD函数创建栈帧

main函数创建栈帧过程:

请添加图片描述

main函数栈帧创建的详细步骤:

1.main函数创建栈帧之前:

请添加图片描述

2.ebp压栈,esp指向开辟空间的顶端并赋值给ebp指针

请添加图片描述

3.esp-e4h即main函数栈帧大小为e4h字节,esp指向main函数栈顶

请添加图片描述

4.ebx、esi、edi压栈并给edi加载有效地址ebp-24h,将edi和ebp之间的9个地址赋值为cc cc cc cc

请添加图片描述

5.给ebp-8,ebp-14,ebp-20h赋初值exa压栈,并将ebp-14h的值传给eax,ecx压栈,并把ebp-8的值传给ecx,这个过程就是函数传参的过程。调用函数ADD之前把call下一句地址压栈

请添加图片描述

至此main函数的函数栈帧的创建和数据初始化就完成了

请添加图片描述


ADD函数栈帧的创建:

请添加图片描述

add函数栈帧的创建和main函数栈帧创建是一样的,需要注意的是,ADD函数执行结束后的返回值保存在了寄存器eax中,就是避免ADD函数栈帧销毁时,主函数无法访问ADD返回值。由此可见函数返回值是如何返回的。

ADD函数栈帧的创建详细过程:

请添加图片描述


3.栈帧的销毁

以ADD函数函数栈帧的销毁为例

请添加图片描述

ADD函数栈帧销毁详细步骤:

请添加图片描述


4.基于函数传参、返回值、初始化赋值、调用、执行结束问题的思考

函数如何传参:

请添加图片描述

函数返回值如何返回:

请添加图片描述

函数中变量如何初始化和赋值:

请添加图片描述

函数如何调用如何返回:

请添加图片描述

函数执行结束后系统进行了什么操作:

请添加图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值