栈,栈帧Stack Frames和函数调用过程Control Flow

news2024/9/23 15:28:34

栈其实就是计算机系统内存中的一小块。栈是一块特殊的内存区域,栈在内存中的增长方向是向低地址扩展,%rsp寄存器存储栈的最低地址,即栈顶元素的地址。这种栈结构在程序中的应用有助于实现函数调用、局部变量的管理以及递归等功能。

 Push和Pop指令

内存中中的栈可以进行push和pop指令,如果你学过数据结构中的栈,基本就是类似的。 

Pushq

pushq Src操作包括以下步骤:

  1. Src获取操作数。
  2. 将%rsp寄存器的值减8(因为x86-64架构中,一个二进制字长度为8字节)。
  3. 将操作数写入%rsp寄存器指向的地址。

通过pushq操作,我们将数据压入栈顶,并更新了栈顶指针%rsp

popq

popq Dest操作包括以下步骤:

  1. 读取%rsp寄存器指向的地址处的值。
  2. 将%rsp寄存器的值加8。(越往上地址越高,这里是向上缩小了)
  3. 将读取到的值存储在Dest(通常是一个寄存器)。

关于pop要注意的是,我们仅仅是把原来的值copy了一份给了Dest, %rsp的值虽然加了8往上移动了,但是原来%rsp所指的值依然存在在内存的那个位置中

程序控制流Control Flow

在程序执行过程中,栈结构被用于支持函数的调用和返回。

函数调用:call指令

当需要调用一个函数时,使用call label指令。它执行以下操作:

  1. 将返回地址(return address)压入栈中。(返回地址是紧跟在call指令后的下一条指令的地址。这一点很好理解,执行完call后就要回来继续往下执行嘛。)
  2. 跳转(jump)至label指定的函数起始位置。

函数返回:ret指令

当函数执行完毕,需要返回到调用它的位置时,使用ret指令。它执行以下操作:

  1. 从栈中弹出地址(pop address from stack)。
  2. 跳转(jump)至弹出的地址。

下面放一个例子,我配上了注释说明,应该很好理解。图中%rip存的是当前执行指令地址,即instruction pointer。

 栈存储额外参数

在我们调用函数时,如果函数的参数少于等于6个,我们可以用%rdi %rsi %rdx %rcx %r8 %r9这几个寄存器分别存储这六个参数,但如果参数多于6个,从第七个开始,我们就会把他们放到栈里。

Stack Frames栈帧

啥是栈帧?当调用一个函数时,会使用 call 指令。call 指令会将返回地址压入栈中,然后跳转到目标函数的起始位置。此时,新的栈帧会被分配和设置,用于存储目标函数的参数、局部变量等。

返回地址属于调用者(上一个函数)的栈帧。当一个函数被调用时,它的返回地址会被call指令压入到当前栈帧的顶部,紧接着就是下一个(被调用)函数的栈帧。

基于栈的编程语言通常支持递归,例如C、Pascal和Java等。这些编程语言的代码必须是"可重入的"(Reentrant),这意味着单个函数可以拥有多个同时进行的实例。为了实现这种功能,我们需要某种方式来存储每个函数实例的状态,包括参数、局部变量和返回指针等。栈规则(Stack Discipline)是为了实现上述需求而采用的策略。对于给定的函数实例,我们只需要在有限的时间内维护其状态,即从函数被调用到函数返回的这段时间。此外,被调用函数(callee)在调用函数(caller)返回之前就需要返回。

为了实现栈规则,我们将栈分配为栈帧。每个栈帧代表单个函数实例的状态。当一个函数被调用时,将为其分配一个新的栈帧,用于存储其参数、局部变量和返回指针等。当函数返回时,将释放其栈帧,从而为其他函数实例提供空间。

栈帧是用于存储函数实例状态的数据结构。每个栈帧包含以下内容:

  1. 返回信息:包括返回地址(return address)和可能的保存的寄存器值。
  2. 局部存储(如果需要的话):用于存储函数内的局部变量。
  3. 临时空间(如果需要的话):用于存储函数执行期间可能需要的临时数据。

栈帧的分配和回收在函数的调用和返回过程中完成:

  1. 分配空间:当进入函数时,先将返回地址压入栈中,再会为其分配一个栈帧。这个过程包括pushq指令(由call指令执行)。
  2. 回收空间:当函数返回时,会释放其栈帧。这个过程包括popq指令(由ret指令执行)将返回地址从栈中弹出。

上面的caller frame就是调用者的栈帧,caller又调用了另一个函数,于是有了新的栈帧。

Caller Saved 和Callee Saved 寄存器

最后再补充两个概念:Caller Saved 和Callee Saved。

当一个函数掉用另一个函数时,另一个函数进行计算时同样会用到寄存器来存储数据,那么难免会影响到前一个函数在寄存器上面的值,因此有这么一种规范或者约定,来帮助程序合理地使用寄存器而不会彼此冲突。

调用方保存寄存器(caller-saved register)也叫( “Call-Clobbered”)

这个术语的意思是,在调用过程(函数或子程序)之前,调用方有责任保存这些寄存器的值。这是因为被调用方可能会修改这些寄存器的值,而不需要负责恢复它们。换句话说,如果调用方关心这些寄存器的值,它需要在调用过程之前将这些值保存到内存中,在调用过程完成并返回后再将它们恢复到寄存器中。

属于caller-saved register的寄存器有:%rdi %rsi %rdx %rcx %r8 %r9 %r10 %r11

被调用方保存寄存器(callee-saved register)也叫(“Call-Preserved”)

当一个函数或子程序(被调用方)计划使用这些寄存器时,它负责在执行过程中保留这些寄存器的初始值,并在过程结束前恢复它们。这样,调用方可以确信在调用过程返回后,这些寄存器的值保持不变。被调用方保存寄存器的目的是减轻调用方的负担,因为它无需为这些寄存器执行保存和恢复操作。因此被调用方保存寄存器和调用方保存寄存器是互补的。

属于callee-saved register的寄存器有:%rbx, %r12, %r13, %r14

简单来说,caller-saved register是会被子函数改变的,调用者要自己通过提前存储的方式保存下来;而callee-saved register是可以保证调用结束后值不变的,调用者不用操心它们~

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

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

相关文章

Blazor 自定义可重用基础组件之 CheckBox

Blazor 原生提供的基础组件实在是一言难尽&#xff0c;这给许多Blazor UI公司很多机会。可是试用了不少如AntDisgen、BootstrapBlazor等&#xff0c;总会有一些难尽如意的地方。还是自己做丰衣足食吧。 首先是带Label的CheckBox&#xff0c;代码如下&#xff1a; <p><…

HTML5开发工程师岗位的职责说明文(合集)

HTML5开发工程师岗位的职责说明文1 职责&#xff1a; 1、根据产品设计文档和视觉文件&#xff0c;利用HTML5&#xff0c;Javascript相关技术实现web端的界面效果、交互和功能; 2、基于HTML5.0的标准进行页面制作&#xff0c;编写可复用的用户界面组件; 3、负责分析和解决前端…

30多个小程序一键发布——miniprogram-ci

概述 miniprogram-ci 是从微信开发者工具中抽离的关于小程序/小游戏项目代码的编译模块。 开发者可不打开小程序开发者工具&#xff0c;独立使用 miniprogram-ci 进行小程序代码的上传、预览等操作。 miniprogram-ci 从 1.0.28 开始支持第三方平台开发的上传和预览&#xff0…

[DBT-05509] Failed to connect to the specified database (orcl).

同事在arm上测试19c部署时&#xff0c;发截图给我说dbca建库有告警&#xff0c;无法进行&#xff0c; Cause- OS Authentication might be disabled for this database (orcl). Action Specify a valid sysdba user name and password to connect to the database. 查找到的…

Windows安装ciphey编码工具,编码工具战神,cry简单题绝对克星!

TA是什么 一款智能化的编码分析解码工具&#xff0c;对于CTF中复杂性编码类题目可以快速攻破。 编码自动分析解码的神器。 如何安装 Windows环境 Python 3.8 64位&#xff08;最新的版本不兼容&#xff0c;32位的也不行&#xff09; 方便起见&#xff0c;我直接给一个3.8.…

【花雕】全国青少年机器人技术一级考试备考实操搭建手册2

目录 1、秋千 2、跷跷板 3、搅拌器 4、奇怪的钟 5、起重机 6、烤肉架 7、手摇风扇 8、履带车 9、直升机 10、后轮驱动车 游乐场里的跷跷板 跷跷板&#xff08;又作翘翘板&#xff09;&#xff0c;又称为摇摇板&#xff0c;是指以某些东西作为支点&#xff0c;支撑著很长但十分…

MongoDB 获取数组中匹配到的第一个元素对象

例如当前test库中的grade集合中有两条文档数据,如下图所示: 相关的两个实体映射类如下: import lombok.Data; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb…

Python中Self的详解及使用

大家学Python面向对象的时候&#xff0c;总会遇到一个让人难以理解的存在&#xff1a;self 这个self到底是谁啊&#xff0c;为什么每个类实例方法都有一个参数self&#xff0c;它到底有什么作用呢&#xff1f; 「先下结论&#xff1a;类实例化后&#xff0c;self即代表着实例&…

[SSM]在WEB中应用MyBtis

目录 MyBatis基础 5.1需求描述 5.2数据库表的设计和准备数据 5.3实现步骤 第一步&#xff1a;引入相关依赖 第二步&#xff1a;引入相关配置文件&#xff0c;放到resources目录下&#xff08;全部放到类的根路径下&#xff09; 第三步&#xff1a;前端页面index.html 第…

Istio 深入理解数据平面组件 Envoy

ingress control承载了控制面和数据面的一个职责&#xff0c;在control里面有一个process&#xff0c;这个进程就承担了反向代理的能力&#xff0c;当有任何请求发过来的时候&#xff0c;会被nginx接收到这个请求并且被转发&#xff0c;基于的规则由ingress control动态配置的&…

2023年7月1日【青书学堂】考试 计算机应用基础(高起专)

2023年7月1日【青书学堂】考试 计算机应用基础(高起专) 注意:答案仅供参考 成绩:88.8 分 第1题 单选题 在Word的编辑状态,按先后顺序依次打开了d1.doC、d2.doC、d3.doC、d4.doc 4个文档,当前的活动窗口的文档名为____。 A:d1.doc B:d2.doc C:d4.doc D:d3.doc 答案:C 第…

php代码还原工具,解决goto语句混淆,php goto解密还原

在编写php代码时&#xff0c;使用goto语句是一种常见的加密技巧。为了解决goto解码无法阅读这个问题&#xff0c;今天我要向大家介绍一款强大的php goto解密工具。 这款工具的主要功能之一就是php代码的还原。通过对代码进行解析和分析&#xff0c;它能够轻松还原被混淆的goto…

vim多文件切换快捷键设置

1、基本切换指令 vim中在打开多个文件时&#xff0c;会有多个文件进行切换的需求。按:bn切换到下一个文件&#xff0c;按:bp切换到上一个文件。 2、快捷键设置 为了便捷操作&#xff0c;将切换命令设置成快捷键。 进入/home/yys个人目录下&#xff0c;vim .vimrc进入vimrc文…

Spring Boot 中的 @EnableDiscoveryClient 注解

Spring Boot 中的 EnableDiscoveryClient 注解 Spring Boot 是一个快速开发 Spring 应用程序的框架&#xff0c;它提供了一些基础设施&#xff0c;使得我们可以快速地开发出高效、可靠的应用程序。其中&#xff0c;EnableDiscoveryClient 注解是 Spring Boot 中一个非常重要的…

C++刷题第四天 链表 24. 两两交换链表中的节点 ● 19.删除链表的倒数第N个节点 ● 160. 链表相交 ● 142.环形链表II

24. 两两交换链表中的节点 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例&#xff1a; 原列表为&#xff1a;1-2-3-4-…

【Mysql】Explain深入分析(三)

Explain工具介绍 使用EXPLAIN关键字可以模拟优化器执行SQL语句&#xff0c;分析你的查询语句或是结构的性能瓶颈 在 select 语句之前增加 explain 关键字&#xff0c;MySQL 会在查询上设置一个标记&#xff0c;执行查询会返回执行计划的信息&#xff0c;而不是执行这条SQL 注意…

node ffmpeg jsmpeg 拉流 展示笔记

拉流参考上一篇 基础&#xff1a;FFmpeg安装过 拉流完成之后转换成可播放的方式 1、下载jsmpeghttps://github.com/phoboslab/jsmpeg 下载完 用vscode 打开jsmpeg-master目录 2、在根目录下安装 node-media-server npm install node-media-server 新建app.js并运行 const…

8 图像去噪 滤波 锐化 边缘检测案例(matlab程序)

1.简述 学习目标&#xff1a;一个图像处理的经典综合案例 一、图像锐化的原理   图像锐化的目的是凸显物体的细节轮廓&#xff0c;通常可以用梯度、Laplace算子和高通滤波来实现&#xff0c;下面一一说明&#xff1a; 1、梯度法 梯度计算可以参考 小白学习图像处理——cann…

数据可视化01_t-SNE

1. t-SNE的定义 t-SNE stands for t-distributed Stochastic Neighbor Embedding. 代表 t 分布随机邻域嵌入。 t-SNE 获取高维数据并将其降低到较低维空间&#xff0c;同时保持数据点之间的关系尽可能接近其原始排列。 它是一种无监督机器学习算法&#xff0c;由 Laurens va…

8年测试经验总结,性能测试流程与性能测试学习路线,卷起来...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试流程 1、…