修炼内功之函数栈帧的创建与销毁

修炼内功之函数栈帧的创建与销毁

  • 一 前置知识
    • (1)栈
    • (2)相关寄存器和汇编指令
  • 二 函数栈帧
  • 三 代码演示函数栈帧的创建
    • (1)代码演示
    • (2)函数栈帧逐帧分析
  • 四 对开篇问题的解答

  相信来CSDN的伙伴们,或多或少对编程都有一定的了解,那本菜鸟来考考你,关于编程的绝命六连问,看看你能答对几个?

1.局部变量是如何创建的?·
2.为什么局部变量不初始化内容是随机的?
3.有些时候屏幕上输出的"烫烫烫"是怎么来的?
4.函数调用时参数时如何传递的?传参的顺序是怎样的?。
5.函数的形参和实参分别是怎样实例化的?
6.函数的返回值是如何返回的?

  或许这些问题一出,有些小伙伴们可能就懵了,我们都知道函数,函数调用,我们也知道局部变量,形参,实参等等,这些我们每次写代码都在用的东西,看似简单,深入思考之后,发现别有洞天,这些告诉我们,学习编程,不可以浮于表面。
  要解决这些问题,我们就得深入理解函数栈帧的创建与销毁。

一 前置知识

(1)栈

  一般我们在学习 C/C ++语言的时候.我们会关注内存中的三个区域:栈区、堆区、静态区。

1.局部变量,函数参数是放在内存的栈区
2.全局变量,静态变量是放在内存的静态区
3.堆区是用来动态内存管理的

在这里插入图片描述

由此,我们知道函数是在栈中开辟空间的,那什么是栈呢?

  栈:在经典的计算机科学中,栈被定义为一种特殊的容器,用户可以将数据压入栈中(入栈, push) ,也可以将已经压入栈中的数据弹出(出栈, pop ),但是栈这个容器必须遵守一条规则:先入栈的数据后出栈 (First ln Last 0ut, FIFO) 。就像叠成一叠的书,先上去的书在最下面,因此要最后才能取出。
  在经典的操作系统中,栈总是向下增长(由高地址向低地址)的。栈顶由成为 esp 的寄存器进行定位的。

(2)相关寄存器和汇编指令

1.相关寄存器

eax :通用寄存器,保留临时数据,常用于返回值ebx :通用寄存器,保留临时数据
ebp :栈底寄存器
esp :栈顶寄存器
eip :指令寄存器,保存当前指令的下一条指令的地址

2.相关汇编指令

mov :数据转移指令
push :数据入栈,同时 esp 栈顶寄存器也要发生改变
pop :数据弹出至指定位置,同时 esp 栈顶寄存器也要发生改变
sub :减法命令
add :加法命令
cal l :函数调用, I. 压入返回地址 2.转入目标函数jump :通过修改 eip,转入目标函数,进行调用
ret :恢复返回地址,压入 eip ,类似 pop eip 命令

二 函数栈帧

  概念:每一次函数的调用,操作系统都会在内存的栈区上开辟一块空间,称为栈帧。函数调用建立栈帧,栈帧中存储局部变量,参数等。
  学习函数的栈帧,就必须要了解ebp,esp(ebp 存放的是栈底的地址,esp 存放的是栈顶的地址,),专门用于维护函数栈帧的。
在这里插入图片描述

三 代码演示函数栈帧的创建

(1)代码演示

#include <stdio.h>
int sum(int x, int y)
{int sum = 0;sum = A + B;return sum;
}
int main()
{int a = 3;int b = 5;int s = 0;s = Add(a, b);printf("%d\n", ret);return 0;
}

  首先,我先简单的声明一下,main函数也是被其他函数调用起来的,在vs2019中, main 函数调用之前,是由invoke-main 函数来调用 main 函数。在 invoke-main 函数之前的函数调用我们就暂时不考虑了。那我们可以确定, invoke-main 函数应该会有自已的栈帧, main 函数和 Add 函数也会维护自已的栈帧,每个函数栈帧都有自已的 ebp 和 esp 来维护栈帧空间。
  那接下来我们从 main 函数的栈帧创建开始讲解:

(2)函数栈帧逐帧分析

1.转到反汇编
在这里插入图片描述
2.逐帧分析如图
在这里插入图片描述

四 对开篇问题的解答

1.局部变量是如何创建的?
在这里插入图片描述
  局部变量的创建是在局部变量所在的函数的栈帧创建完成并初始化后,然后在该栈帧内为局部变量分配空间的。
2.为什么局部变量不初始化其内容是随机的?
  因为编译器在创建函数栈帧后会在栈帧空间里面放入一个值,而这个值是随机的。
3.有些时候屏幕上输出的"烫烫烫"是怎么来的?

#include<stdio.h>
int main()
{
char arr[20];
printf("%s\n",arr);
return 0;
}

  调试输出“烫烫烫……”的原因,是因为main函数调用时,在栈区开辟的空间的其中每一个字节都被初始化为0xCC,而arr数组是一个未初始化的数组,恰好在这块空间上创建的,0xCCCC(两个连续排列的0xCC)的汉字编码就是“烫”,所以0xCCCC被当作文本就是“烫”。
4 ,函数调用时参数时如何传递的?传参的顺序是怎样的?
在这里插入图片描述

  我们在调用函数之前,就会在栈顶上从右向左依次压入需要传递的参数,在创建好被调函数的函数栈帧后通过指针的偏移量来使用传递过去的参数,而不是在被调函数的函数栈帧内创建形参。
5 .函数的形参和实参的关系是什么?
  形参是实参的一份临时拷贝,二者的存储亻立置不同,形参的改变不会影响实参。
6 .函数的返回值是如何带回的?
在这里插入图片描述

  函数的返回值通过 eax寄存器带回。
(完)

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

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

相关文章

QT用Enigmavb 打包成单独exe

QT用这个工具打包成单个exe&#xff0c;然后再用winrar打包成zip可以发给别人 在之前需要用QT的release打包 之前的文章QTrelease打包【非单个exe】 Enigmavb 打包流程&#xff1a; 安装过程&#xff1a; next-》i accept -》选择安装位置 -》next -》Create a desktop ic…

图的最短路径(C++实现图【4】)

目录 1. 最短路径 1.1单源最短路径--Dijkstra算法 代码实现 1.2 单源最短路径--Bellman-Ford算法 代码实现 1.3 多源最短路径--Floyd-Warshall算法 代码实现 1. 最短路径 最短路径问题&#xff1a;从在带权有向图G中的某一顶点出发&#xff0c;找出一条通往另一顶点的最短路径&…

udp tcp协议

文章目录 1. UDP协议1.1 端口号1.2 UDP协议格式1.3 UDP特性1.4 报文的封装 2. TCP协议2.1 TCP协议格式2.2 TCP策略2.2.1 确认应答机制(ACK)序号与确认序号6个标志位序号的理解 2.2.2 超时重传机制2.2.3 连接管理机制三次握手四次挥手理解三次握手理解四次挥手 2.2.4 流量控制2.…

提高保养效率:4S店预约系统的设计与开发

3.1可行性分析 开发者在进行开发系统之前&#xff0c;都需要进行可行性分析&#xff0c;保证该系统能够被成功开发出来。 3.1.1技术可行性 开发该4S店预约保养系统所采用的技术是vue和MYSQL数据库。计算机专业的学生在学校期间已经比较系统的学习了很多编程方面的知识&#xff…

支付域——支付路由设计

摘要 本文深入探讨了支付路由系统的背景、核心作用、设计原则以及业界常见形态。文章详细解析了支付方式咨询、渠道咨询和渠道路由的概念&#xff0c;并介绍了支付路由的规则种类、交易参数、通道属性和常见筛选规则。进一步讨论了基于规则的渠道路由设计、自动化开关的渠道路…

leetcode 面试经典 150 题:螺旋矩阵

链接螺旋矩阵题序号54题型二维数组&#xff08;矩阵&#xff09;解题方法模拟路径法难度中等熟练度✅✅✅ 题目 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3…

保护模式基本概念

CPU 架构 RISC&#xff08;Reduced Instruction Set Computer&#xff09; 中文即"精简指令集计算机”。RISC构架的指令格式和长度通常是固定的&#xff08;如ARM是32位的指令&#xff09;、且指令和寻址方式少而简单、大多数指令在一个周期内就可以执行完毕 CISC&…

突发!!!GitLab停止为中国大陆、港澳地区提供服务,60天内需迁移账号否则将被删除

GitLab停止为中国大陆、香港和澳门地区提供服务&#xff0c;要求用户在60天内迁移账号&#xff0c;否则将被删除。这一事件即将引起广泛的关注和讨论。以下是对该事件的扩展信息&#xff1a; 1. 背景介绍&#xff1a;GitLab是一家全球知名的软件开发平台&#xff0c;提供代码托…

git Force Push失败:unable to access解决方案

git Force Push失败&#xff1a;unable to access 项目场景&#xff1a;问题描述原因分析&#xff1a;解决方案&#xff1a;1、访问github远程仓库&#xff0c;更新推送规则1、打开代码库&#xff0c;点击settings2、在settings中下翻&#xff0c;在Danger Zone中将点击Disable…

工业相机镜头选型知识详解

工业相机在机器视觉、自动化生产和检测等领域扮演着重要角色&#xff0c;而镜头作为工业相机的关键组件&#xff0c;其选型直接影响到成像效果和系统的整体性能。在本篇博客中&#xff0c;我们将详细讲解工业相机镜头选型的相关知识&#xff0c;帮助您在实际应用中选择最合适的…

安装CPU版的torch(清华源)

1、安装指令&#xff1a; pip3 install torch torchvision torchaudio -i https://pypi.tuna.tsinghua.edu.cn/simple2、验证torch是否安装成功 // 使用python验证 import torch print(torch.__version__)能正常打印版本即表示安装成功&#xff0c;如下图

‘pnpm’ 不是内部或外部命令,也不是可运行的程序或批处理文件。

‘pnpm’ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 1.情况: npm -v 和 node -v的都正常就是 pnpm-v 无效 检查环境变量也没看出问题 2.分析 没有正确添加环境变量 3.解决 找到npm的全局安装目录 npm list -g --depth 0这里出现了npm的全局安装…

Java 日志类库

Java 日志库是最能体现 Java 库在进化中的渊源关系的&#xff0c;在理解时重点理解日志框架本身和日志门面&#xff0c;以及比较好的时间等。要关注其历史渊源和设计&#xff08;比如桥接&#xff09;&#xff0c;而具体在使用时查询接口即可&#xff0c;否则会陷入 JUL&#x…

聚类之轮廓系数

Silhouette Score&#xff08;轮廓系数&#xff09;是用于评估聚类质量的指标之一。它衡量了数据点与同簇内其他点的相似度以及与最近簇的相似度之间的对比。 公式 对于一个数据点 i&#xff1a; a(i): 数据点 i 到同簇内其他点的平均距离&#xff08;簇内不相似度&#xff…

问题小记-达梦数据库报错“字符串转换出错”处理

最近遇到一个达梦数据库报错“-6111: 字符串转换出错”的问题&#xff0c;这个问题主要是涉及到一条sql语句的执行&#xff0c;在此分享下这个报错的处理过程。 问题表现为&#xff1a;一样的表结构和数据&#xff0c;执行相同的SQL&#xff0c;在Oracle数据库中执行正常&…

【电路笔记 信号】Metastability 平均故障间隔时间(MTBF)公式推导:进入亚稳态+退出亚稳态+同步器的可靠性计算

这是一个简化的电路分析模型。图2中的典型触发器包括主锁存器、从锁存器和去耦反相器(这个结构类似 主从边沿触发器)。 在亚稳态中&#xff0c;主锁存器的节点A、B的电压电平大致在逻辑“1”&#xff08;VDD&#xff09;和“0”&#xff08;GND&#xff09;之间。确切的电压电平…

【C++】B2066救援题目分析和解决讲解

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af; 题目&#x1f4af; 题目分析每个屋顶计算的元素 &#x1f4af; 思路解析1. **读取输入**2. **计算屋顶时间**3. **结果精确取整** &#x1f4af; 完整解决代码&#x1f4a…

springboot创建web项目

一、创建项目 二、导入依赖&#xff08;pom.xml&#xff09; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schem…

RAID5原理简介和相关问题

1、RAID5工作原理 2、RAID5单块硬盘的数据连续吗&#xff1f; 3、RAID5单块硬盘存储的是原始数据&#xff0c;还是异或后的数据&#xff1f; 4、RAID5的分块大小 ‌RAID5的分块大小一般选择4KB到64KB之间较为合适‌。选择合适的分块大小主要取决于以下几个考量因素&#xff1…

重温设计模式--模板方法模式

文章目录 一、模板方法模式概述二、模板方法模式UML图三、优点1代码复用性高2可维护性好3扩展性强 四、缺点五、使用场景六、C 代码示例1七、 C 代码示例2 一、模板方法模式概述 定义&#xff1a;定义一个操作中的算法骨架&#xff0c;而降一些步骤延迟到子类中。模板方法使得…