从汇编层看64位程序运行——栈帧(Stack Frame)边界

news2024/11/15 4:18:18

大纲

  • RBP,RSP
  • 栈帧边界
  • 总结
  • 参考资料

在《从汇编层看64位程序运行——栈帧(Stack Frame)入门》中,我们简单介绍了栈帧的概念,以及它和函数调用之间的关系。如文中所述,栈帧是一种虚拟的概念,它表达了一个执行中的函数的栈空间区域。在这个区域中,该函数的局部非静态变量便被置于这个空间中,即我们常常说起的栈上变量。

那么这个区间是通过什么划分的?

RBP,RSP

这就需要引入寄存器这个概念。

寄存器(Register)是中央处理器内用来暂存指令、数据和地址的存储器。 寄存器的存贮容量有限,读写速度非常快。 在计算机体系结构里,寄存器存储在已知时间点所作计算的中间结果,通过快速地访问数据来加速计算机程序的执行。

CPU有非常多的寄存器,本节我们主要讲解与栈帧相关的两个寄存器:

  • 栈底指针寄存器(Stack Base pointer register): 在16位系统中,有个寄存器叫bp;在32位系统中,这个寄存器叫ebp;在64位系统中,这个寄存器叫rbp。
  • 栈顶指针寄存器(Stack pointer register): 在16位系统中,有个寄存器叫sp;在32位系统中,这个寄存器叫esp;在64位系统中,这个寄存器叫rsp。

需要注意的是,栈底指针寄存器(rbp)保存的并不是当前栈帧的栈底地址,而是保存了栈上变量分配的起始地址
如下图,0x7fffffffdf20到0x7fffffffdf10是main函数栈帧的部分,它保存了函数调用需要用到的一些信息(我们在《从汇编层看64位程序运行——函数的调用和栈平衡》将会介绍)。从0x7fffffffdf10开始的内存,保存的是main函数局部非静态变量的值。
在这里插入图片描述
栈顶指针寄存器(rsp)不仅可以被直接设置,还会随着栈上Push和Pop的操作而改变。这个特性和rbp有很大不同,rbp只能直接被设置,栈上Push和Pop操作并不会直接导致rbp的值发生变动。
如果函数有局部非静态变量,则在函数开始时,编译器会计算好这个函数需要的局部变量空间,然后通过调整rsp的值(值变小,即栈增长),来声明当前函数的栈上变量空间。
比如下面代码的反汇编,在汇编代码的+8行,通过sub $0x10,%rsp,让当前函数的栈扩展了0x10个字节。

int main() {
    int b = 16;
    b = b + 16;
    foo();
    return 0;
}

在这里插入图片描述

栈帧边界

有了上述的铺垫,我们通过info stack和info frame来查看到程序运行到foo函数时的栈帧
在这里插入图片描述
可以看到一个函数的栈帧起始地址是上一个栈帧的rsp,栈帧结束地址该函数进入下一栈帧前的rsp
在这里插入图片描述
需要注意的是“该函数进入下一栈帧前的rsp并不一定等于局部变量空间的最后一个地址
因为在局部变量空间之后,调用者函数可能还需要将一些参数Push到栈中,从而传递给调用者。这个时候rsp会继续扩张。于是栈帧的结束地址也在扩张。关于这块知识我们可以在《从汇编层看64位程序运行——参数传递的底层实现》中看到。
正因为存在需要使用栈来给不同函数传递参数的情况,让一个函数的栈帧的结束地址是持续变化的。比如一个函数调用的A,需要栈上传递1个参数;这个函数调用的B,需要栈上传递2个参数。那么相较于进入A函数,进入B函数时调用者函数的栈帧就要更大些(大1个参数空间)。
如下图main函数的栈帧在它调用不同函数时,其栈帧的结束地址是持续变化的。
在这里插入图片描述

总结

  • 栈帧运行时虚拟的结构。
  • 函数的栈帧起始地址是调用者调用本函数时RSP的值。
  • 函数的栈帧的结束地址分为两种情况:
    • 有调用其他函数时。结束地址是调用其他函数时RSP的值。
    • 没有调用其他函数时。结束地址是栈上最后一个变量的结束地址。
  • 栈帧的结束地址可能会随着其调用其他函数而不停改变。

参考资料

  • https://www.eecg.utoronto.ca/~amza/www.mindsec.com/files/x86regs.html

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

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

相关文章

Python之Excel自动化处理(二)

一、Excel设置样式 1.1、常用方法与属性 函数名&属性含义xlwt.Font()创建字体样式font.name设置字体类型font.colour_index设置字体颜色font.height设置字体大小font.bold设置字体是否为加粗font.underline设置字体下划线font.italic设置字体斜体xlwt.Alignment()创建字体…

笔记 1 : 课本前 2 章

现在开始跟着彭老师学习 arm 。把重要的知识点归拢一下,便于复习。早日学有所成,为国为家为己,更幸福些。 (1)冯诺依曼架构与哈弗架构,与混合架构: 以及: (2&#xff0…

音视频入门基础:H.264专题(13)——FFmpeg源码中通过SPS属性获取视频色彩格式的实现

一、引言 通过FFmpeg命令可以获取到H.264裸流文件的色彩格式(又译作色度采样结构、像素格式): 在vlc中也可以获取到色彩格式(vlc底层也使用了FFmpeg进行解码): 这个色彩格式就是之前的文章《音视频入门基础…

03-Charles实战

一、抓包分析问题示例 1)问题描述 2)抓包分析 这是后台响应回来的错误信息,说明问题一是后台的原因;但是后台只响应了一条信息,而前端页面却显示两条错误信息,说明前端页面处理异常的时候逻辑有问题&#…

《昇思25天学习打卡营第3天|03张量Tensor》

说在开始 学习下mindspore中对tensor的处理逻辑。 Tensor属性 张量的属性包括形状、数据类型、转置张量、单个元素大小、占用字节数量、维数、元素个数和每一维步长。 形状(shape):Tensor的shape,是一个tuple。 数据类型&…

windows USB 设备驱动开发- USB Type-C支持(一)

传统的 USB 连接使用两端都有 USB A 和 USB B 接头的电缆。 USB A 连接器始终插入主机端,USB B 连接器连接功能端,该功能端是手机) 或外设 (鼠标、键盘) 的设备 (。 使用这些连接器,只能将主机连接到函数;绝不是另一个主机的主机或另一个函数…

如何安装dotenv,避坑指南,安装包的包名有误?

嗨,大家好,我是蓝若姐姐。最近在研究AI大模型,想写一个调用openai接口的demo,结果发现在装一个三方库的时候一直报错,mac电脑安装dotenv报错,具体情况是 执行这个命令: pip install dotenv 遇…

提升 Kubernetes 日志记录能力,提高可观察性

介绍 在微服务和容器化应用时代,有效管理和监控应用的健康和性能至关重要。Kubernetes是一个用于自动部署、扩展和管理容器化应用的开源系统,已成为寻求敏捷性和弹性的企业的首选解决方案。 然而,由于 Kubernetes 的分布式架构、高日志量和…

【数据结构】栈和队列的深度探索,从实现到应用详解

💎所属专栏:数据结构与算法学习 💎 欢迎大家互三:2的n次方_ 🍁1. 栈的介绍 栈是一种后进先出的数据结构,栈中的元素只能从栈顶进行插入和删除操作,类似于叠盘子,最后放上去的盘子最…

Git代码管理工具 — 4 Git分支详解

目录 1 Git 分支概念 2 Git 分支基本操作 2.1 git branch查看与创建本地分支 2.2 git checkout切换分支 2.3 git merge合并分支 2.4 删除分支 3 解决冲突 1 Git 分支概念 Git 分支允许你从当前开发线上分离出来,进行独立的开发工作,而不会影响主…

用 AI 写歌词,让音乐表达与众不同

在音乐的广袤天地中,我们都渴望通过独特的表达来触动人心,展现自我。而如今,AI 技术的崛起为音乐创作带来了全新的突破,让我们能够以一种前所未有的方式赋予音乐独特的灵魂。 “妙笔生词智能写歌词软件(veve522&#…

Window10下安装WSL-Ubuntu20.04

1.开启并更新WSL 1.1开启WSL 首先先来看一下电脑是否能够开启WSL:待补充... 然后再来看一下如何开启WSL:win->设置->应用->应用和功能->程序和功能,如下所示: 最后选择启用或关闭Windows功能,开启两个选项:1.Hyper-V…

大语言模型诞生过程剖析

过程图如下 📚 第一步:海量文本的无监督学习 得到基座大模型🎉 🔍 原料:首先,我们需要海量的文本数据,这些数据可以来自互联网上的各种语料库,包括书籍、新闻、科学论文、社交媒体帖…

K8S系列-Kubernetes基本概念及Pod、Deployment、Service的使用

一、Kubernetes 的基本概念和术语 一、资源对象 ​ Kubernetes 的基本概念和术语大多是围绕资源对象 Resource Object 来说的,而资源对象在总体上可分为以下两类: 1、某种资源的对象 ​ 例如节点 Node) Pod 服务 (Service) 、存储卷 (Volume)。 2、…

记录些Redis题集(4)

Redis 通讯协议(RESP) Redis 通讯协议(Redis Serialization Protocol,RESP)是 Redis 服务端与客户端之间进行通信的协议。它是一种二进制安全的文本协议,设计简洁且易于实现。RESP 主要用于支持客户端和服务器之间的请求响应交互…

Adminer-CVE-2021-21311

在其4.0.0到4.7.9版本之间,连接 ElasticSearch 和 ClickHouse 数据库时存在一处服务端请求伪造漏洞(SSRF)。 VPS开启HTTP服务 VPS 开启HTTP 再同时跑POC 确保能访问poc里的链接文件 第一是目标地址 第二个是跳转地址 第三个是监听地址 如果…

昇思25天学习打卡营第21天|DCGAN生成漫画头像

DCGAN原理 DCGAN(深度卷积对抗生成网络,Deep Convolutional Generative Adversarial Networks)是GAN的直接扩展。不同之处在于,DCGAN会分别在判别器和生成器中使用卷积和转置卷积层。 它最早由Radford等人在论文Unsupervised Re…

【软件建模与设计】-03-软件生存周期模型和过程

目录 1、瀑布模型 2、抛弃型原型 3、演化式-增量模型 4、螺旋模型 5、统一软件开发过程RUP 6、设计验证和确认 6.1、软件质量保证 6.2、软件设计的性能分析 7、软件生存周期的活动 7.1、需求分析和规约 7.2、体系结构设计 7.3、详细设计 7.4、编码 8、软件测试 …

element-ui 插槽自定义样式怎么居中

场景:使用element-ui组件,scope内部自定义样式导致的错位 效果图: 解决思路: template标签可理解为一个内嵌组件,宽高重新定义,可在自定义内容外层套一层盒子,让盒子占满所有空间,再…

DBA 数据库管理 表管理 数据批量处理。表头约束

表管理 建库 库名命名规则:仅可以使用数字、字母、下划线、不能纯数字 不可使用MySQL命令或特殊字符 库名区分字母大小写 加if not exists 命令避免重名报错 create database if not exists gamedb; 建表 drop database if exists gamedb ; 删表…