前言

网上很多对函数栈的解释,说的不是很清楚感觉,尤其是对到底是谁的栈,以及指令的微小但是很致命的细节没说,特写本文,一是帮助自己记忆,二是为了帮助大家,如有疏忽错误请指正。

核心概念

首先明白几个概念
1、在x86系统的CPU中,rsp是栈指针寄存器,这个寄存器中存储着栈顶的地址。rbp中存储着栈底的地址。函数栈空间主要是由这两个寄存器来确定的。
2、其次 x86 栈高处是高地址,低处是低地址,rsp 向下增长(sub rsp n)。
3、⚠️警告:有的汇编语言写法是这样的 mov %rbp,%rspmov rsp rbp 是等价的。

基本x86架构的栈就是下图这个样子:
在这里插入图片描述

解释函数调用前后栈变化

一、函数调用首先都是先执行 call 指令,这个指令执行后做了两件事:

1、把“返回地址”压入栈(即下一条指令的地址);
说明:如果使用 python 解释,比如 main 函数中的一条指令要调用 add 函数了,这里的下一条指令指的是 add(a,b) 的下一条指令。另外压入的这个栈是调用函数自己的栈,而不是被调用函数

2、跳转到目标函数的入口地址(jmp)。

二、建立被调用函数的栈
执行如下指令,建立被调用函数的栈:

push rbp
mov rbp rsp

push rbp #调用函数将自己栈的栈底( rbp 寄存器中的值)压入被调用函数的栈里,并且 rsp 自动向下移动,指向刚才压入的值处(但是 rbp 寄存器中的值没变化)
说明:rsp 是自己移动的,至于移动多少取决于你 push 进的数据有多长,这个 cpu 电路自己能判断,不用人为干预。
mov rbp rsp #将rsp 寄存器中的值复制到 rbp 寄存器中(这时候被调用函数的栈底和栈顶指向同一处即保存调用函数栈底的位置)

三、函数调用完成后执行如下指令:

mov rsp, rbp   ; 恢复栈顶(rsp)到函数基址(rbp)
pop rbp        ; 恢复调用者的 rbp(基址指针)
ret            ; 隐式执行:pop rip(从栈顶弹出返回地址 → 写入 rip)

mov rsp, rbp ; 恢复栈顶(rsp)到函数基址(rbp)
是函数返回前常见的一步,将 rbp 寄存器中的值复制到 rsp 寄存器中,这时候 rbp 和 rsp 指向同一个地址,并且被调用函数的栈就只有一个元素,即调用函数的栈底地址,它的本质作用是撤销本函数在栈上为局部变量分配的空间,恢复 rsp 到进入函数时的位置。

pop rbp 将调用函数的栈底地址弹出到 rbp 寄存器,这时候,被调用函数的栈被销毁。并且 rsp 自动向上指向调用函数栈的栈顶(即返回值)。

ret 是 return from procedure 的缩写,它做了两件事:
1、从当前栈顶也就是调用函数的栈顶(rsp 指向的位置)弹出一个地址(返回地址);返回地址就是上文讲过的比如python 代码中的 add(a,b) 的下一条指令的地址。
2、把这个地址加载到 rip(指令指针寄存器),程序跳转回调用函数的下一条指令继续执行。

由于函数完成调用后的栈变化比较复杂,容易混淆,所以再次总结下函数调用完成后的堆栈变化:

mov rsp, rbp   ; 恢复栈顶(rsp)到函数基址(rbp)
pop rbp        ; 恢复调用者的 rbp(基址指针)
ret            ; 隐式执行:pop rip(从栈顶弹出返回地址 → 写入 rip) 

第一条指令执行后,rsp 指向被调用函数的 rbp ;
然后pop rbp 后,rsp 指向被调用函数的上一个地址,即调用函数的栈里边了(此时被调用函数的栈被销毁掉了已经);
然后执行 ret 后,就把 rsp 指向的东西弹出到 rip 里。
从这里可以看出函数下一条要执行的指令,即返回地址,是调用者自己保存到自己的栈中的。

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

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

相关文章

基于Apache MINA SSHD配置及应用

Apache MINA SSHD 是一个基于 Java 的 SSH 服务器和客户端实现,它是 Apache MINA 项目的一部分,提供了完整的 SSH 协议支持。 主要特性 SSH 协议支持: 支持 SSH2 协议 兼容大多数 SSH 客户端 支持多种加密算法和密钥交换方法 服务器功能…

Excel 如何让数据自动按要求排序或筛选?

让数据按要求排序和筛选是Excel数据处理的基础核心功能,也是进行有效分析前必做的准备工作。下面我们分开讲解这两个功能。 一、排序 (Sort):让数据井井有条 排序的目的是重新排列数据行的顺序,以便更好地观察和比较。 1. 快速单列排序 (最…

Django 安装使用教程

一、Django 简介 Django 是一个高级 Python Web 框架,鼓励快速开发和简洁实用的设计。它内置 ORM、认证系统、后台管理、表单处理、路由控制等功能,广泛用于开发企业级网站、内容管理系统、电商平台等。 二、环境准备 2.1 安装 Python Django 基于 Py…

前沿交叉:Fluent与深度学习驱动的流体力学计算体系

基础模块 流体力学方程求解 1、不可压缩N-S方程数值解法(有限差分/有限元/伪谱法) Fluent工业级应用:稳态/瞬态流、两相流仿真(圆柱绕流、入水问题) Tecplot流场可视化与数据导出 2、CFD数据的AI预处理 基于P…

五、Flutter动画

目录1. Flutter 中动画的基本概念是什么?2. 解释 AnimationController 和 Tween 的作用3. 如何实现一个补间(Tween)动画?4. 什么是隐式动画?举例说明5. 如何实现自定义复杂动画?1. Flutter 中动画的基本概念…

全网唯一/Qt结合ffmpeg实现手机端采集摄像头推流到rtsp或rtmp/可切换前置后置摄像头/指定分辨率帧率

一、前言说明 之前已经实现了Qt结合ffmpeg在安卓上运行,所有在win上的功能,在安卓上都已经实现,比如编码保存到MP4文件,正常解码音视频文件播放等,唯独还差一个功能,尽管用的不多,但是还是有一…

Install Ubuntu 24.04 System

1.制作安装镜像盘(U盘) 下载rufus制作工具(网址:https://www.xiaomoxz.com/nexus/bi1/rufus4.shtml?bd_vid8643969197265870719) 2. 设置U盘启动: F2进入BIOS 3. Install Ubuntu 24.04 Ubuntu下载地址:…

solidjs 处理复杂类型的响应式

solidjs 处理复杂类型的响应式 在 solidjs 里响应式一般直接用 createSignal 就可以,但 createSignal 一般用于基础数据类型。 虽然复杂类型也是可以使用,但基于起细粒度响应性的特性。 一般复杂的数据使用 createSignal 就不是那么友好了。 所以 cre…

爬虫技术-获取浏览器身份认证信息(如 Cookie、Token、Session 等)

方法一:通过浏览器开发者工具查看和提取 Cookie / Token 📌 示例场景: 你在使用一个网站时已经登录了,想看看这个网站是如何保存你的身份凭证的。 🔧 操作过程: 打开浏览器(例如 Chrome&#xf…

[密码学实战]GMT 0136-2024《密码应用HTTP接口规范》解析

[密码学实战]GM/T 0136-2024《密码应用HTTP接口规范》解析国家密码管理局于2025年7月1日正式实施GM/T 0136-2024标准,该规范首次统一了密码服务的HTTP接口设计,为国产密码技术的规模化应用铺平道路。本文结合标准原文,深入剖析其技术细节并给…

Docker 国内镜像列表(免费长期)

Docker 可用镜像源列表(7月1日更新-长期维护)_dockerhub国内镜像源列表-CSDN博客

BlenderFBXExporter 导出fbx被修改问题

1) 解决增加A节点的问题 https://github.com/A-Ribeiro/CustomBlenderFBXExporter 2)找出blendshape 不一致,生成blendshape key name映射map 文件compare.txt C:\Users\49938\Documents\DazToUnreal\zhang01\UpdatedFBX\zhang01_fix7.fbx…

AI时代下的IT服务管理转型:趋势、挑战与破局之道

近年来,人工智能(AI)与自动化技术的迅猛发展,正以前所未有的速度重塑企业运营的各个层面。特别是在IT服务管理(ITSM)领域,AI的介入不仅提高了问题响应效率,也推动了组织从“被动响应…

三体融合实战:Django+讯飞星火+Colossal-AI的企业级AI系统架构

目录 技术栈关键词:Django 5.0 讯飞星火4.0Ultra Colossal-AI 1.2 WebSocket 联邦学习 ⚡ 核心架构设计 🛠️ 一、Django深度集成讯飞星火API(免费版) 1. 获取API凭证 2. 流式通信改造(解决高并发阻塞&#xff09…

多模态数据融合预警:从IoT传感器到卫星监测的可视化方案升级

你有没有想过,为什么有些城市在暴雨来临时能提前数小时发布内涝预警,而有些地方却只能“等水来了才反应”? 背后的关键,就是多模态数据融合预警系统——它把来自IoT传感器、无人机、地面雷达、气象站、甚至卫星的数据整合在一起&a…

面试八股---css

2、css 2.1 说说你对盒子模型的理解 是什么 当对一个文档进行布局(layout)的时候,浏览器的渲染引擎会根据标准之一的 CSS 基础框盒模型(CSS basic box model),将所有元素表示为一个个矩形的盒子&#xf…

day52-硬件学习之RTC及ADC

一、RTCRTC(实时时钟):非易失性在IMX6ULL内部SNVS(安全的非易失性存储器)提供RTC功能;原理图:二、ADC 2.1 基本概念ADC(模拟数字转换器):用于将连续变化的模拟信号转换为离散的数字信…

Web 项目如何自动化测试?

Web 项目的自动化测试可以通过 UI自动化 和 接口自动化 结合实现,提高测试效率和覆盖率。以下是关键方法和工具: 【自动化测试】从基础到实战基于Pytest自动化/python自动化的详细教程!1. UI自动化测试(前端交互) 适用…

Java连接阿里云MaxCompute例

要使用Java连接阿里云MaxCompute(原名ODPS)数据库,您可以遵循以下步骤进行配置和编程: 1. 添加依赖 确保您的项目中包含了MaxCompute JDBC驱动的依赖。如果您使用Maven,可以在pom.xml中添加如下依赖: &l…

【网络与系统安全】强制访问控制——BLP模型

一、模型背景与定义 BLP(Bell-LaPadula)模型是由David Bell和Len Adula在1973年提出的强制访问控制(MAC)模型,是最早的计算机安全模型之一,主要用于解决多用户系统中的信息机密性保护问题,尤其…