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

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

  • 一 前置知识
    • (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…

云原生后端开发(一)

云原生后端开发 云原生&#xff08;Cloud-Native&#xff09;是指一种构建和运行应用程序的方式&#xff0c;它充分利用了云计算的特点&#xff0c;比如弹性伸缩、自动化部署、容器化等。在云原生的架构下&#xff0c;后端应用通常具备高度可扩展、可维护、易于自动化管理的特…

图的最短路径(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.…

【C++ 基础】从C到C++有哪些变化

C到C C相比C语言来说&#xff0c;多了两个核心&#xff0c;五个内容&#xff1a;1、面向对象的思维&#xff1b;2、模板&#xff08;泛型编型&#xff09;1.bool 2.引用 3.内联 4.重载 5.缺省参数变量 数据类型 bool 布尔 占1个字节 取值&#xff1a;true false bool isMax(i…

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

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

支付域——支付路由设计

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

TORCH_CUDA_ARCH_LIST

目录 查看方法&#xff1a; 设置方法&#xff1a; 查看方法&#xff1a; python -c "import torch; print(torch.cuda.get_device_capability())" 设置方法&#xff1a; 通过代码设置&#xff1a; 在你的 Python 脚本中&#xff0c;使用 os.environ 来设置 TORCH_…

WebAuthn 项目常见问题解决方案

WebAuthn 项目常见问题解决方案 webauthn Webauthn / passkeys helper library to make your life easier. Client side, server side and demo included. [这里是图片001] 项目地址: https://gitcode.com/gh_mirrors/webaut/webauthn 项目基础介绍 WebAuthn 项目是一个开源…

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

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

【设计模式】空接口

&#xff08;空&#xff09;接口的用法总结 接口用于定义某个类的特定能力或特性。在工作流或任务管理系统中&#xff0c;接口可以帮助标识哪些任务可以在特定阶段执行。通过实现这些接口&#xff0c;任务类可以被标识为在相应的阶段可以执行&#xff0c;从而在验证和执行逻辑…

保护模式基本概念

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;帮助您在实际应用中选择最合适的…

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——13使用Resnet-Bin

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——13使用Resnet-Bin ​ 根据前面的内容&#xff0c;目前已经可以获取到resnet的bin模型 1 .Resnet的bin测试 ​ 这里给大家一个测试视频里面黑线的demo&#xff0c;大家可以用来测试自己的黑线识别精度 …

Rust: offset祼指针操作

offset是偏移元素个数&#xff0c;不是字节数&#xff01; fn main(){let student_a Student{id:20240001,name:"张三娃".into(),class_id:3,age:14,grade:1};let student_b Student{id:20240002,name:"李四牛".into(),class_id:3,age:15,grade:1};let …

安装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…