C语言函数的栈帧与销毁(面试亮点)

目录

如果你能熟练的掌握函数的栈帧与销毁在面试中是及其亮眼的加分项,所以我们来以实例来将解函数是如何实现栈帧与销毁的。

一. 函数栈帧

二.寄存器

三. 用例题讲解创建栈帧的过程

3.1 main 函数的反汇编代码。

第一步:给调用main函数的函数分配栈帧。 

第二步:通过将edp压栈,将edp赋值给esp,再将esp的值减减。这样esp和edp之间的差值就是main函数的栈帧空间。 

第三步: 将edi,esi,ebx压栈。

第四步:初始化

 第五步:给实参分配空间

第六步:将实参拷贝到新地址

第七步: call指令传参

call跳add()函数的地址之后,在添加call指令的下一条指令的地址。

3.2 add函数的栈帧 

第一步:为add创建栈帧

第二步:将形参相加:

3.3 return  的栈帧

第一步

z出了add()栈帧被销毁,但是值被临时放到eax寄存器里。

第二步

第三步:回收空间

第四步:pop edp 

第五步:回来之后执行call指令的下一条指令 

第六步 

创建的完整过程(没带销毁)

四.面试问题

4.1 局部变量时怎么创建的?

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

4.3 函数是怎么传参的?传参的顺序是什么? 

4.4 形参和实参的关系是什么?

4.5 函数的调用是怎么做的?

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


如果你能熟练的掌握函数的栈帧与销毁在面试中是及其亮眼的加分项,所以我们来以实例来将解函数是如何实现栈帧与销毁的。

一. 函数栈帧

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

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

二.寄存器

1.1 edp:栈底指针

1.2 esp:栈顶指针,每次push,它都会向上(低地址)挪动,push就会--,pop就会++。

esp和edp中间的 内容才是当前维护的内容,esp上方的内容已经销毁的内容

 寄存器:寄存器是集成到CPU 上的是独立的存储空间。与硬盘,内存都是独立存在的。

三. 用例题讲解创建栈帧的过程

 

3.1 main 函数的反汇编代码。

main函数也是被调用,main函数是被t_main CRTStartup调用。

第一步:给调用main函数的函数分配栈帧。 

第二步:通过将edp压栈,将edp赋值给esp,再将esp的值减减。这样esp和edp之间的差值就是main函数的栈帧空间。 

 

第三步: 将edi,esi,ebx压栈。

lea:是load effective address 是加载有效地址的意思。即esp-014H。

 

第四步:初始化

从edi开始向下ecx次即39h次,将ecx里dword(一个word两个字节,doubleword是四个字节)个内容初始化为0cccccccch,初始化39h(39h是十六进制,换成十进制次)次。即将main函数里的内容全部初始化为0cccccccch。 

所以如果变量不初始化,那么就默认0cccccccch。

 

 

 第五步:给实参分配空间

将ebp-14h(即b的值)存放到eax里,然后将eax压栈 。

  


 

第六步:将实参拷贝到新地址

不用给形参分配新空间,在函数调用之前,就将实参拷贝到新空间。

 

第七步: call指令传参

call的地址是

然后call指令,call指令跳到add()函数的地址

call跳add()函数的地址之后,在添加call指令的下一条指令的地址。

所以call()指令之后,将call指令的下一条指令的地址压栈。

 

 

3.2 add函数的栈帧 

然后才是真正的进入add()函数。 

 

第一步:为add创建栈帧

所以我们并没有创建形参,而是在调用函数的时候就把实参传递过去了。 将他们当成X,Y。

因此可以证明形参只是实参的拷贝。所以改变形参不会改变实参。

 

第二步:将形参相加:

 

 

3.3 return  的栈帧

形参是实参的临时拷贝,不是在add栈帧里创建的只是调用一个压栈的空间。 

第一步

  

z出了add()栈帧被销毁,但是值被临时放到eax寄存器里。

所以为了防止z出了作用域被销毁,所以将z放到eax寄存器里临时保存,寄存器是不会因为程序销毁而销毁的。 

第二步

 

pop会导致esp++ ,esp上面的栈会被释放被回收了S。

 

第三步:回收空间

 将ebp赋值给esp的意思就是将esp挪动到edp的位置,上面的空间被回收。

 

第四步:pop edp 

pop edp,将edp出栈,这里栈顶元素edp是main函数的edp,所以将他pop之后他会回到原main函数的edp位置。

然后esp++;这是esp和edp两个指针彻底回到main函数的作用域里。esp指向00C21450即回到了call指令的下一条指令的地址,所以要执行call指令的下一条指令。

第五步:回来之后执行call指令的下一条指令 

 

 

  

将esp+8:这里加8的目的值将两个形参的空间给销毁。

 

 

第六步 

 

 将eax的值赋值给edp -20h,刚刚我们为了防止z的值丢失所以我们将它的值存放在寄存器eax里,所以函数的任务完成了,现在需要将操作完的值还给main函数。

正好edp-20h就是main函数的C。这样返回值就被传回来了。

 

 

创建的完整过程(没带销毁)

四.面试问题

4.1 局部变量时怎么创建的?

        答:首先,我们为这个局部变量分配栈帧空间,然后在为这个空间初始化空间,然后在为局部变量分配空间。

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

        答:因为如果局部变量不初始化的话,函数栈帧空间的初始化是随机值,所以如果局部变量不初始化的话,那么它的值就是它分配的那段空间的随机值。如果你将局部变量初始化了,那么你初始化的值就会覆盖掉随机值。

4.3 函数是怎么传参的?传参的顺序是什么? 

        我们并没有创建形参,而是在调用函数的时候就把实参传递过去了。在还没有调用函数的时候,就以及将实参的拷贝push压栈到空间里,到调用函数的时候,并没有为形参分配空间,而是使用esp+偏移量,找到实参的拷贝。

        传参的顺序:参数从右向左压栈。

4.4 形参和实参的关系是什么?

        答:形参是实参的拷贝,改变形参不会影响实参。因为他们的空间是独立的。

4.5 函数的调用是怎么做的?

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

        在函数调用之前就将call指令的下一条指令的地址就压栈了,然后再将edp(此时的edp是调用函数的上一条函数如main函数的edp)压栈,这样在pop掉edp时,edp会返回到原edp的位置,由于pop操作,会使esp++,这样esp就会调用call指令的下一条指令的地址,这样就会时函数调用返回,然后返回的值,事先已被寄存器eax临时保存,这样值也会被寄存器带回。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/676511.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[职场] 如何通过运营面试_1 #笔记#媒体#经验分享

如何通过运营面试 盈利是公司的事情,而用户就是你运营的事情。你需要彻底建立一个庞大而有效的用户群,这样才能让你们的公司想盈利就盈利,想战略就战略,想融资就融资。 一般从事运营的人有着强大的自信心,后台数据分析…

JVM-虚拟机栈

虚拟机栈 Java虚拟机栈(Java Virtual Machine Stack)采用栈的数据结构来管理方法调用中的基本数据,先进后出(First In Last Out),每一个方法的调用使用一个栈帧(Stack Frame)来保存。 接下来以…

vue3 之 通用组件统一注册全局

components/index.js // 把components中的所组件都进行全局化注册 // 通过插件的方式 import ImageView from ./ImageView/index.vue import Sku from ./XtxSku/index.vue export const componentPlugin {install (app) {// app.component(组件名字,组件配置对象)…

D7 Elasticsearch-Mongodb(搜索记录)

我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! 知…

mysql笔记:表设计原则

mysql笔记:表设计原则 表对应了一个实体 表与表之间的关系: 一对一 一对多 多对多 一对一关系 例如:用户 user和身份信息 info 子表的外键关联了父表的子健(类型必须一样) 一对多关系 以电商系统为例子 用户-商…

CSP-202012-1-期末预测之安全指数

CSP-202012-1-期末预测之安全指数 题目很简单&#xff0c;直接上代码 #include <iostream> using namespace std; int main() {int n, sum 0;cin >> n;for (int i 0; i < n; i){int w, score;cin >> w >> score;sum w * score;}if (sum > 0…

使用 Ant Design 的 Upload 组件实现图片

文章目录 使用 Ant Design 的 Upload 组件实现图片Upload组件itemRender自定义上传列表项的渲染方式修改图片名上传图片上传链接中添加 Bearer Token 的请求头onPreview{handlePreview}上传成功后&#xff0c;如何隐藏上传列表 使用 Ant Design 的 Upload 组件实现图片 Upload…

【第二十三课】最小生成树:prime 和 kruskal 算法(acwing858,859 / c++代码 )

目录 前言 Prime算法--加点法 acwing-858 代码如下 一些解释 Kruskal算法--加边法 acwing-859 并查集与克鲁斯卡尔求最小生成树 代码如下 一些解释 前言 之前学最短路的时候&#xff0c;我们都是以有向图为基础的&#xff0c;当时我们提到如果是无向图&#xf…

【深度学习】实验7布置,图像超分辨

清华大学驭风计划 因为篇幅原因实验答案分开上传&#xff0c; 实验答案链接http://t.csdnimg.cn/P1yJF 如果需要更详细的实验报告或者代码可以私聊博主 有任何疑问或者问题&#xff0c;也欢迎私信博主&#xff0c;大家可以相互讨论交流哟~~ 深度学习训练营 案例 7 &#xff1…

计算机毕业设计Python+django医院后勤服务系统flask

结合目前流行的 B/S架构&#xff0c;将医疗后勤服务管理的各个方面都集中到数据库中&#xff0c;以便于用户的需要。该平台在确保平台稳定的前提下&#xff0c;能够实现多功能模块的设计和应用。该平台由管理员功能模块,工作人员模块&#xff0c;患者模块&#xff0c;患者家属模…

基于SpringBoot的记账系统项目

点击以下链接获取源码&#xff1a;https://download.csdn.net/download/qq_64505944/88822660?spm1001.2014.3001.5503 Java项目-8 开发工具&#xff1a;IDEA/Eclipse,MySQL,Tomcat 项目框架&#xff1a;SpringBoot,layui 功能&#xff1a;可以按照类型和时间查询&#xff0c…

基于tomcat运行jenkins常见的报错处理

目录 1.jenkins.util.SystemProperties$Listener错误 升级jdk11可能遇到的坑 2.java.lang.RuntimeException: Fontconfig head is null, check your fonts or fonts configuration 3.There were errors checking the update sites: UnknownHostException:updates.jenkins.i…

notepad++成功安装后默认显示英文怎么设置中文界面?

前几天使用电脑华为管家清理电脑后&#xff0c;发现一直使用的notepad软件变回了英文界面&#xff0c;跟刚成功安装的时候一样&#xff0c;那么应该怎么设置为中文界面呢&#xff1f;具体操作如下&#xff1a; 1、打开notepad软件&#xff0c;点击菜单栏“Settings – Prefere…

Modern C++ 内存篇1 - std::allocator VS pmr

大年三十所写&#xff0c;看到就点个赞吧&#xff01;祝读者们龙年大吉&#xff01;当然有问题欢迎评论指正。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. 前言 从今天起我们开始内存相关的话题&#xff0c;内存是个很大的话题&#xff0c;一时不…

探索未来:集成存储器计算(IMC)与深度神经网络(DNN)的机遇与挑战

开篇部分&#xff1a;人工智能、深度神经网络与内存计算的交汇 在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;已经成为科技领域的一股强大力量&#xff0c;而深度神经网络&#xff08;DNN&#xff09;则是AI的核心引擎之一。DNN是一种模仿人类神经系统运作…

sqli.bypass靶场本地小皮环境(1-5关)

1、第一关 http://sqli.bypass/index1.php 单引号报错id1 双引号正常id1&#xff0c;应该是单引号闭合 id1--注释符用不了&#xff0c;%20和都用不了 %0a可以用 没有报错&#xff0c;用布尔盲注&#xff0c;POC&#xff1a;id1%0aand%0asubstr(ss,1,1)s%0aand%0a11 脚本跑数…

大模型学习笔记二:prompt工程

文章目录 一、经典AI女友Prompt二、prompt怎么做&#xff1f;1&#xff09;注重格式&#xff1a;2&#xff09;prompt经典构成3&#xff09;简单prompt的python询问代码4&#xff09;python实现订阅手机流量套餐的NLU5&#xff09;优化一&#xff1a;加入垂直领域推荐6&#xf…

GPT-4模型中的token和Tokenization概念介绍

Token从字面意思上看是游戏代币&#xff0c;用在深度学习中的自然语言处理领域中时&#xff0c;代表着输入文字序列的“代币化”。那么海量语料中的文字序列&#xff0c;就可以转化为海量的代币&#xff0c;用来训练我们的模型。这样我们就能够理解“用于GPT-4训练的token数量大…

从一到无穷大 #23 《流计算系统图解》书评

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言内容总结 引言 春节假期回到家里断然是不会有看纸质书的时间的。造化弄人&#…

HCIA--ACL和远程登陆实验

1.划分网段&#xff0c;配IP地址&#xff0c;启用OSPF协议&#xff1a; AR1配置&#xff1a; [Huawei]sys R1 [R1]int g0/0/0 [R1-GigabitEthernet0/0/0]ip add 192.168.1.1 24 [R1-GigabitEthernet0/0/0]int g0/0/1 [R1-GigabitEthernet0/0/1]ip add 12.1.1.1 24 [R1-Gigabi…