<C语言>函数栈帧的创建和销毁

函数栈帧的创建和销毁

在此之前先强调一句话:函数栈帧的创建和销毁的过程,在不同编译器下他的创建和销毁过程是略有差异的,具体差异取决于编译器。但大体是一致的。

寄存器

什么是寄存器?

寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果以及一些CPU运行需要的信息。

寄存器的名称和功能
名称功能
eax通常用来执行加法,函数调用的返回值一般也放在这里面
ebx数据存取
ecx通常用来作为计数器,用于循环操作,重复的字符存储操作或数字统计
edx读写I/O端口时,edx用来存放端口号
esp栈顶指针,指向栈的顶部
ebp栈底指针,指向栈的底部,通常用 ebp+偏移量 的形式来定位函数存放在栈中的局部变量
esi字符串操作时,用于存放数据源的地址
edi字符串操作时,用于存放目的地址的,和esi两个经常搭配一起使用,执行字符串的复制等操作

ebp和esp这两个寄存器存放的是地址,用来维护函数栈帧

每一个函数调用,都要在栈区创建一块空间

汇编指令

名称功能
push把字压入堆栈,给栈顶放一个元素。在32位平台上,esp每次减少4字节。
mov将一个数据从源地址传送到目标地址,源操作地址的内容不变
sub减法
lea“load effective address”的缩写,用来将一个内存地址直接赋给目的操作数。
pop出栈,从栈顶删除一个元素。在32位平台上,esp每次增加4字节。
rep缩写 repeat, 重复前缀指令,能够引发其后字符串指令被重复。
cmp比较指令
jmp无条件跳转
add两个运算子相加,结果写入第一个运算子
ret终止当前函数的执行,将运行权交还给上层函数
stos串存储指令,英文缩写 store string。
call调用函数

数栈帧的创建销毁过程

为了更好理解函数栈帧的创建和销毁过程,下面简单举个例子:

#include <stdio.h>

int Add(int x,int y)
{
	int z = 0;
	z = x + y;
	return z;
}

int main()
{
	int a = 3;
	int b = 4;
	int c = 0;

	c = Add(a, b);

	printf("%d", c);
	return 0;
}

按下F10,在调试->窗口打开调用堆栈,这里比较推荐低版本的编译器,版本越低观察越清楚。

image-20230118171721617

这儿我们发现mian函数被调用起来了

image-20230118172433626

main函数是被谁调用了呢?

image-20230118173741408

在VS2022中,main函数是被 scrt_common_main_seh 函数调用,而 scrt_common_main_seh 函数是被 invoke_main 函数调用。

image-20230118174832360

为了更详细观察我们转到反汇编,按下F10,右击鼠标转到反汇编

image-20230120100426826

同时也打开监视窗口,在调试状态下执行以下操作

image-20230123180335837

栈是从高地址向低地址延伸的。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低地址)。

main函数栈帧开辟

在这里插入图片描述

word,是2个字节,dword是双字的意思,也就是4字节

main函数栈帧开辟动态演示

在这里插入图片描述

最终开辟静态图

在这里插入图片描述

main函数中变量创建

image-20230123180655317

在监视窗口查找以下信息:

image-20230123180757723

根据上图,我们知道了0Ah,14h和0的位置,执行mov命令便会出现如下情况,仔细观察image-20230123181918277image-20230123181952148image-20230123182033313三个位置

shuangxiangbenfu1552

在main函数创建变量最终效果图

main函数传参过程

由main函数中变量已知a,b

image-20230123203335223

执行过程

9

main函数中的变量创建好且传参之后,调用Add 函数,调用之前要先给Add函数开辟栈帧,过程类似于给main函数创建栈帧。

Add函数栈帧开辟

Add函数栈帧开辟动态演示

在这里插入图片描述

最终开辟静态图

Add函数中变量创建及运行

image-20230124094859203

在监视窗口查看以下信息:


Add函数销毁过程

在这里插入图片描述

返回函数栈帧

返回到call指令的下一条指令地址

image-20230124181413838

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

艾莜薇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值