剖析函数栈帧的创建与销毁,斯高一版本!!

简介: 剖析函数栈帧的创建与销毁,斯高一版本!!

寄存器

寄存器有哪些

32位寄存器有16个,分别是:

4个数据寄存器(EAX、EBX、ECX、EDX)。

2个变址和指针寄存器(ESI和EDI);2个指针寄存器(ESP和EBP)。

6个段寄存器(ES、CS、SS、DS、FS、GS)。

1个指令指针寄存器(EIP);1个标志寄存器(EFlags)。

寄存器分别有什么作用

简单的汇编指令

ebp、esp这两个寄存器中存放的是地址,这两个地址是用来维护函数栈帧的。每一个函数调用,(相当于领域展开)都要在栈区创建一个空间。(我的记忆方法是sb表示高低顺序(手动狗头))

上实操!

代码

#define _CRT_SECURE_NO_WARNINGS 1
#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\n", c);
  return 0;
}

函数栈帧讲解

main函数的函数栈帧创建

首先打破大家一个固有观点,main函数也是被其他函数调用的,具体如下图(call就是调用)

在创建main函数函数栈帧前esp和ebp是维护tmianCRTStartup函数的。

(下图是没有创建main函数前的esp和ebp位置)

首先是push ebp将ebp指针存放地址进行压栈操作,esp向上移动指向ebp压栈,就是下图蓝色小矩形,(每一次pushy,esp都会向上移动)是将tmianCRTStartup函数的栈底指针存放起来,便于销毁时能够找寻(销毁时会讲具体原理),然后是mov ebp,esp,意思是将esp的地址赋值给ebp,然后是sub esp,0E4h,意思是将esp减去一个16进制的数0E4h,esp往上移(往低地址移),这个16进制的数可以看成是main函数函数栈帧的大小。

一顿操作后就是这个样子

接下来push三连击,每压一次压栈,esp都会向上移动,然后是lea edi,[edp-24h]指令,意思是将地址edp-24加载到edi中去。

接下来意思是将edi以下的9个空间的值都赋为0CCCCCCCCh(这里就解释了当你不初始化变量时为什么是随机值)

一顿操作后就是下面这个样子

调用函数的函数栈帧创建过程

函数变量

mov三连击,分别将0Ah、14h和0的值放到[ebp-8]、[ebp-14h]和[ebp-20h]三个地址内也就是给这三个变量盖房子。

Add函数函数栈帧的创建

这里讲解的就是函数的传参问题,也就是解释了为什么传int这种变量时无法对实参的值进行修改,先打个预防针(形参是实参的临时拷贝);

在创建Add函数的函数栈帧前进行传参操作

mov eax,dword ptr [ebp-14h]

push eax

mov ecx,dword ptr [ebp-8]

push ecx

这几条指令的意思就是将[ebp-14h]和[ebp-8]中存放的值分别赋给eax和ecx,并它们压在栈顶。(这里有一个小细节就是先传b,再传a);

传参之后就是在原图加上上面的ecx eax

在进入函数前我们压入函数调用完执行的下一条代码的地址,以便进入函数内部后再出来后能够找到所需要执行的下一条代码

接下来进入函数内部和main函数的函数栈帧创建一样,大家自行理解,如果有不懂得可以评论区留言或者是私信我’

一顿操作下面就是add的函数栈帧

接下来执行Add函数内部的代码

函数返回值

将0存放到[ebp-8]的空间中去,然后将[ebp+8]存放的值(a=10)赋给eax,再然后给eax加上[ebp+0Ch]存放的值(b=20),此时eax的值为30,再将eax的值存放到[ebp-8]的空间中去,而[ebp-8]这个地址存放的就是z。最后执行return z语句,相应的汇编代码就是mov eax,dword ptr [ebp-8],将[ebp-8]存放的值赋给eax,现在eax的值就是30了。重点(eax就是存放函数返回值的寄存器)

函数栈帧销毁

Add函数执行完毕后就开始销毁

pop三连击,将edi,esi,ebx弹出栈,然后mov esp,ebp意思是将ebp指针赋值给esp,然后弹出ebp,这里ebp就回到了main函数的栈底,

然后执行ret返回到call执行的下一条语句

回来之后,给esp加上8,那么esp就向下移,此时形参x和y的空间也销毁了。接下来的指令是,将eax的值放到[ebp-20h]的空间中去,而[ebp-20]这个空间存放的就是变量c,相当于将eax的值赋给c,那么Add函数的返回值就成功地带回来了。最后就是将c的值打印在屏幕上了。

然后就是main函数的销毁,大家也是自行理解,我就不做赘述了

最后总结几个问题

1.局部变量是如何创建的?

当main函数的函数栈帧创建好之后,然后在函数栈帧中给局部变量开辟一个空间。

2.为什么局部变量的值是随机值?

因为编译器会给函数栈帧里的空间放入随机值,而局部变量也是在函数栈帧中开辟空间的,所以局部变量的值是随机值。

3.函数是如何传参的?传参的顺序是怎么样的?

将b和a的值分别存在寄存器eax、ecx,然后把eax和ecx压在栈顶。再通过地址找到eax和ecx,也就是形参,将形参加起来,就这样完成了函数的传参。传参的顺序是从右往左传。

4.形参和实参是什么什么关系?

形参和实参的值是相同的,空间上是独立的,形参只是实参的一份临时拷贝,对形参的修改不会影响实参。

5.函数调用是怎么做的呢?

通过esp和ebp的移动来为调用的函数开辟函数栈帧,然后再将执行函数里的代码。

6.函数调用结束后是怎么返回的?

在调用函数之前,就把call指令的下一条指令的地址压在栈顶了,再将main函数的ebp也进行压栈。调用完函数之后,pop main函数的ebp,ebp就会重新指向main函数的栈底。然后通过call指令的下一条指令的地址找回到call的下一条指令,继续往后执行,至此被调用函数的函数栈帧就被销毁了,通过函数的返回值也通过寄存器eax带回来了。


ok今天的分享到这里就结束了,希望大家三连一波狠狠的支持博主一下!!!感谢

目录
相关文章
|
10天前
|
机器学习/深度学习 人工智能 JSON
构建AI智能体:二十八、大语言模型BERT:原理、应用结合日常场景实践全面解析
BERT是谷歌2018年推出的革命性自然语言处理模型,采用Transformer编码器架构和预训练-微调范式。其核心创新在于双向上下文理解和掩码语言建模,能有效处理一词多义和复杂语义关系。BERT通过多层自注意力机制构建深度表示,输入融合词嵌入、位置嵌入和段落嵌入,输出包含丰富上下文信息的向量。主要应用包括文本分类、命名实体识别、问答系统等,在搜索优化、智能客服、内容推荐等领域发挥重要作用。
313 10
|
并行计算 C++ 异构计算
Nvidia 并行计算架构 CUDA 分析(一)——CUDA 简介
    CUDA(Compute Unified Device Architecture,统一计算设备架构)是由 NVIDIA 推出的通用并行计算架构,该架构使 GPU 能够解决复杂的计算问题。
6206 0
|
7月前
|
人工智能 自然语言处理 知识图谱
Yuxi-Know:开源智能问答系统,基于大模型RAG与知识图谱技术快速构建知识库
Yuxi-Know是一个结合大模型RAG知识库与知识图谱技术的智能问答平台,支持多格式文档处理和复杂知识关系查询,具备多模型适配和智能体拓展能力。
1769 55
Yuxi-Know:开源智能问答系统,基于大模型RAG与知识图谱技术快速构建知识库
|
6月前
|
JavaScript 前端开发 中间件
除了 Pinia,还有哪些状态管理库可以实现类似的中间件功能?
除了 Pinia,还有哪些状态管理库可以实现类似的中间件功能?
317 73
|
5月前
|
人工智能 自然语言处理 测试技术
🧠 用 AI 提升你的编程效率 —— 在 PyCharm 中体验通义灵码
通义灵码是一款基于大模型的智能编程辅助工具,现已上线PyCharm插件V2.5+版本。它能根据自然语言描述、注释或上下文生成高质量代码,支持多语言(Python、Java等),提供代码补全、优化建议、单元测试生成及异常排查等功能。集成魔搭MCP市场3000+服务,具备编程智能体模式与长期记忆能力,助开发者提升效率。适用初学者、资深开发者及团队协作场景。小红书、B站、抖音、微博均有相关资源分享。 小红书: http://xhslink.com/a/SvabuxSObf3db bilibili:https://b23.tv/1HJAdIx 抖音: https://v.douyin.com/1DAG
2628 4
|
9月前
|
供应链 监控 数据可视化
优化酒店供应链结构:实现成本控制与效率提升
本文探讨了酒店行业在激烈竞争中如何通过成本控制和供应链优化提升运营效率。具体措施包括精细化预算管理、优化人力资源配置、节能减排、供应商管理、采购流程优化及库存管理。引入可视化管理工具如板栗看板,可进一步提高项目管理、数据分析和信息共享的效率,助力酒店在不牺牲服务质量的前提下降低运营成本,增强市场竞争力。
|
JSON 小程序 前端开发
小程序-云函数-本地调试技巧
小程序-云函数-本地调试技巧
1085 0
|
存储 安全 网络安全
蜜罐技术:如何跟踪攻击者的活动
【10月更文挑战第22天】蜜罐是一种用于网络安全的系统,通过模拟漏洞吸引攻击者,记录其行为以研究攻击手法。分为高交互和低交互两种类型,前者提供真实操作系统服务,后者仅模拟部分系统功能。蜜罐有助于收集恶意软件样本,分析攻击者行为,提高网络安全防御。
376 3
|
算法 网络协议 网络安全
政务单位免费IP地址SSL证书
政务单位申请免费IP地址SSL证书需先确认IP地址为公网IP并拥有管理权限,选择如JoySSL等提供免费测试证书的服务商。申请流程包括注册账号、选择证书类型、提交申请、验证信息、等待审核签发、下载安装证书。注意事项包括安全性、合规性、定期更新及技术支持。通过合理配置,可提升网站安全性和公信力。