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.hqwc.cn/news/465309.html

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

相关文章

计算机毕业设计SSM基于的冷链食品物流信息管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: vue mybatis Maven mysql5.7或8.0等等组成,B…

网络安全工程师技能手册(附学习路线图)

关键词:网络安全入门、渗透测试学习、零基础学安全、网络安全学习路线 安全是互联网公司的生命,也是每位网民的基本需求。现在越来越多的人对网络安全感兴趣,愿意投奔到网络安全事业之中,这是一个很好的现象。 很多对网络安全感…

使用securecrt+xming通过x11访问ubuntu可视化程序

windows使用securecrtxming通过x11访问ubuntu可视化程序 windows机器IP:192.168.9.133 ubuntu-desktop20.04机器IP:192.168.9.190 windows下载xming并安装 按照图修改xming配置 开始->xming->Xlaunch 完成xming会在右下角后台运行 windows在…

爬虫练习——动态网页的爬取(股票和百度翻译)

动态网页也是字面意思:实时更新的那种 还有就是你在股票这个网站上,翻页。他的地址是不变的 是动态的加载,真正我不太清楚,只知道他是不变的。如果用静态网页的方法就不可行了。 静态网页的翻页,是网址是有规律的。 …

政安晨:梯度与导数~示例演绎《机器学习·神经网络》的高阶理解

这篇文章确实需要一定的数学基础,第一次接触的小伙伴可以先看一下我示例演绎这个主题的前两篇文章: 示例演绎机器学习中(深度学习)神经网络的数学基础——快速理解核心概念(一): 政安晨&#…

工业级加固平板丨亿道三防平板电脑丨安卓工业平板丨改善车队管理

在现代物流和运输行业中,车队管理是一个复杂而重要的任务。为了更好地管理车队,提高工作效率和减少成本,许多企业正在采用新技术和工具。其中,三防平板电脑作为一种功能强大且适应恶劣环境的设备,已经在车队管理中得到…

【2024年数据】67个“绿色金融”主题DID政策汇总(已去重)

DID”发文趋势和主题分布 数据来源:中国知网、各期刊官网 时间跨度:2017-2024年 数据范围:中国各省 数据指标: 序号 用于构建DID的政策 文献标题 1 “宽带中国” 数字技术创新与中国企业高质量发展——来自企业数字专利的证据…

unity学习案例总结

动态标签 GitHub - SarahMit/DynamicLabel3D: Simple dynamic labels for a 3D Unity scene

(已解决)将overleaf上的文章paper上传到arxiv上遇到的问题。

文章目录 前言初级问题后续问题 前言 首先说一点,将paper的pdf文件直接上传arxiv是不行的,arxiv要求我们要上传源文件,所以才这么麻烦。 初级问题 首先上传文件之后有可能会在下面这个界面出现问题,这里一般都比较常见的问题&a…

QT学习文件操作类 QFile

(一)QFile QFile 是 Qt 框架中用于文件处理的一个类。它提供了读取和写入文件的功能,支持文本和二进制文件。QFile 继承自 QIODevice ,因此它可以像其他 IO 设备一样使用。 (1)主要功能 1. 文件读写…

C#在窗体正中输出文字以及输出文字的画刷使用

为了在窗体正中输出文字,需要获得输出文字区域的宽和高,这使用MeasureString方法,方法返回值为Size类型; 然后计算输出的起点的x和y坐标,就可以输出了; using System; using System.Collections.Generic; …

LSF 主机状态 unreach 分析

在LSF集群运行过程中,有主机状态变为 unreach。熟悉LSF的朋友都知道主机状态为 unreach 表示主机上的 SBD 服务中断服务了,但其它服务 LIM 和 RES 还在正常运行。 影响分析 那么主机上的 SBD 服务中断的影响是什么呢? 我们需要先明白 SBD …