【CPU】堆栈和堆栈指针(个人草稿)

详细的 CPU 中堆栈指针(Stack Pointer, SP)及相关知识介绍

1. 什么是堆栈?

堆栈(Stack) 是一种后进先出(LIFO, Last In First Out)的数据结构,广泛用于计算机系统中,尤其是在程序执行过程中管理函数调用、局部变量、返回地址等。堆栈通常位于内存的特定区域,称为 堆栈段栈区

  • 特性
    • 后进先出(LIFO):最后入栈的数据最先被弹出。
    • 自动管理:大多数编程语言和操作系统会自动管理堆栈的分配和释放,程序员不需要手动操作。
    • 快速访问:由于堆栈的操作(如压栈和弹栈)非常简单,因此访问速度较快。
2. 堆栈指针(Stack Pointer, SP)

堆栈指针(SP) 是一个特殊的寄存器,用于指向当前堆栈的顶部(即最后一个被压入堆栈的数据项)。每次有数据被压入或弹出堆栈时,堆栈指针都会相应地更新,以确保它始终指向堆栈的最新位置。

  • 作用
    • 指示堆栈顶部:SP 寄存器保存了当前堆栈的顶部地址,使得处理器可以快速访问最新的数据。
    • 动态调整:随着程序的执行,函数调用、局部变量的创建和销毁会导致堆栈的大小发生变化,SP 会根据这些变化动态调整。
    • 支持函数调用:在函数调用时,返回地址、参数和局部变量会被压入堆栈,而 SP 会相应地移动。当函数返回时,SP 会恢复到调用前的位置。
3. 堆栈的工作原理

堆栈的工作原理可以通过以下步骤来理解:

  1. 初始化堆栈

    • 在程序启动时,操作系统会为每个进程分配一段内存作为堆栈空间,并将 SP 初始化为该内存区域的顶部(或底部,取决于堆栈的增长方向)。
    • 堆栈通常从高地址向低地址增长(称为 向下生长),但有些架构也可能从低地址向高地址增长(称为 向上生长)。RISC-V 默认采用 向下生长 的堆栈。
  2. 压栈(Push)

    • 当需要将数据压入堆栈时,CPU 会执行 push 指令(或等效操作)。首先,SP 会减小(对于向下生长的堆栈),然后将数据写入新的堆栈顶部。
    • 例如,在 RISC-V 中,sp 寄存器会减去 4 字节(32 位系统)或 8 字节(64 位系统),然后将数据存储到该地址。
  3. 弹栈(Pop)

    • 当需要从堆栈中弹出数据时,CPU 会执行 pop 指令(或等效操作)。首先,从当前堆栈顶部读取数据,然后 SP 会增加(对于向下生长的堆栈),从而恢复到之前的状态。
    • 例如,在 RISC-V 中,sp 寄存器会加上 4 字节(32 位系统)或 8 字节(64 位系统),然后从该地址读取数据。
  4. 函数调用与返回

    • 函数调用:当调用一个函数时,返回地址、参数和局部变量会被压入堆栈。SP 会相应地移动,指向新的堆栈顶部。
    • 函数返回:当函数执行完毕时,局部变量会被弹出堆栈,返回地址会被恢复,控制流返回到调用者。SP 会恢复到调用前的位置。
4. 堆栈帧(Stack Frame)

堆栈帧 是每次函数调用时在堆栈上创建的一个独立区域,用于存储该函数的局部变量、参数、返回地址等信息。每个函数调用都会创建一个新的堆栈帧,函数返回时会销毁该帧。

  • 堆栈帧的组成
    • 返回地址:函数调用时,返回地址会被压入堆栈,以便在函数执行完毕后能够正确返回到调用点。
    • 参数:函数的参数也会被压入堆栈,供被调用函数使用。
    • 局部变量:函数内部声明的局部变量会被分配在堆栈帧中。
    • 旧的基址指针(Base Pointer, BP):某些架构(如 x86)使用基址指针(BP)来引用堆栈帧中的数据。在进入函数时,旧的 BP 会被保存,新的 BP 会被设置为当前堆栈帧的起始位置。
5. 基址指针(Base Pointer, BP)

基址指针(BP) 是另一个重要的寄存器,通常用于引用当前堆栈帧中的数据。与堆栈指针(SP)不同,BP 通常指向堆栈帧的固定位置,使得函数可以方便地访问参数和局部变量。

  • 作用

    • 引用堆栈帧中的数据:BP 通常指向堆栈帧的起始位置,使得函数可以使用相对偏移量来访问参数和局部变量。这使得代码更加清晰和易于维护。
    • 保存旧的基址指针:在进入函数时,旧的 BP 会被保存到堆栈中,新的 BP 会被设置为当前堆栈帧的起始位置。函数返回时,BP 会恢复到调用前的状态。
  • 示例(x86 架构):

    push ebp        # 保存旧的基址指针
    mov ebp, esp    # 设置新的基址指针
    sub esp, 16     # 为局部变量分配空间
    

    在这段代码中,ebp 被用来引用当前堆栈帧中的数据,而 esp 则继续作为堆栈指针使用。

6. 堆栈溢出(Stack Overflow)

堆栈溢出 是指堆栈的空间被耗尽,导致无法再分配新的堆栈帧或压入更多数据。堆栈溢出通常是由于递归调用过深、局部变量过多或缓冲区溢出引起的。

  • 后果

    • 程序崩溃:如果堆栈溢出,程序可能会崩溃,甚至导致系统不稳定。
    • 安全漏洞:堆栈溢出可能导致缓冲区溢出攻击,黑客可以通过这种漏洞注入恶意代码并执行。
  • 预防措施

    • 限制递归深度:避免过深的递归调用,或者使用迭代代替递归。
    • 检查堆栈大小:在编写代码时,确保堆栈的大小足够大,以容纳所有必要的数据。
    • 使用栈保护机制:现代操作系统和编译器提供了栈保护机制(如栈金丝雀),可以在检测到堆栈溢出时立即终止程序,防止进一步的损害。
7. 堆栈与堆的区别

虽然堆栈和堆都是用于动态内存管理的,但它们的工作方式和用途不同:

  • 堆栈(Stack)

    • 自动管理:堆栈由编译器和操作系统自动管理,程序员不需要手动分配或释放内存。
    • 快速访问:堆栈的操作非常简单,访问速度较快。
    • 有限大小:堆栈的大小是固定的,通常较小,适合存储局部变量、函数调用信息等短期使用的数据。
    • 后进先出(LIFO):堆栈遵循 LIFO 规则,最后入栈的数据最先被弹出。
  • 堆(Heap)

    • 手动管理:堆由程序员手动分配和释放内存,通常使用 mallocfree 等函数。
    • 灵活分配:堆的大小可以根据需要动态扩展,适合存储全局变量、动态分配的对象等长期使用的数据。
    • 无序访问:堆没有固定的顺序,数据可以随意分配和释放。
    • 较慢访问:由于堆的管理较为复杂,访问速度相对较慢。
8. RISC-V 中的堆栈指针

RISC-V 架构中,堆栈指针通常使用 x2 寄存器(也称为 sp),专门用于管理堆栈。RISC-V 的堆栈默认是从高地址向低地址生长(即向下生长),这意味着每次压栈时,sp 会减小;每次弹栈时,sp 会增加。

  • 典型指令
    • 压栈addi sp, sp, -16(将 sp 减少 16 字节,为局部变量分配空间)
    • 弹栈addi sp, sp, 16(将 sp 增加 16 字节,释放局部变量占用的空间)
    • 保存返回地址sw ra, 0(sp)(将返回地址保存到堆栈顶部)
    • 恢复返回地址lw ra, 0(sp)(从堆栈顶部恢复返回地址)
9. 总结
  • 堆栈 是一种后进先出(LIFO)的数据结构,广泛用于管理函数调用、局部变量和返回地址。
  • 堆栈指针(SP) 是一个特殊的寄存器,用于指向当前堆栈的顶部。它会随着数据的压栈和弹栈操作动态调整。
  • 堆栈帧 是每次函数调用时在堆栈上创建的一个独立区域,用于存储函数的局部变量、参数和返回地址。
  • 基址指针(BP) 用于引用堆栈帧中的数据,使得函数可以方便地访问参数和局部变量。
  • 堆栈溢出 是指堆栈空间耗尽,可能导致程序崩溃或安全漏洞。应采取适当的预防措施,如限制递归深度和使用栈保护机制。
  • 堆栈与堆 的主要区别在于堆栈是自动管理的、快速访问的,而堆是手动管理的、灵活分配的。

希望这个详细的介绍能帮助你更好地理解 CPU 中的堆栈指针及其相关概念。如果你有任何具体问题或需要进一步的解释,欢迎继续提问! 😊

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

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

相关文章

设计模式 行为型 策略模式(Strategy Pattern)与 常见技术框架应用 解析

策略模式(Strategy Pattern)核心思想是将算法的实现从使用该算法的类中分离出来,作为独立的对象,通过接口来定义算法家族,这样就可以很容易地改变或扩展算法。通过这种方式,可以避免在客户端代码中使用大量…

如何使用脚手架工具开始,快速搭建一个 Express 项目的基础架构

前言 将从如何使用脚手架工具开始,快速搭建一个 Express 项目的基础架构。接着,文章将详细讲解 Express 中间件的概念、分类以及如何有效地使用中间件来增强应用的功能和性能。最后,我们将讨论如何制定合理的接口规范,以确保 API …

《Opencv》基础操作详解(5)

接上篇:《Opencv》基础操作详解(4)-CSDN博客 目录 接上篇:《Opencv》基础操作详解(4)-CSDN博客 25、轮廓近似 简介 接口用法 参数说明 返回值 代码示例 结果展示 26、轮廓最小外接圆 简介 接口用…

Java虚拟机面试题:内存管理(上)

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…

测试用例颗粒度说明

当我们在编写测试用例时,总是会遇到一个问题:如何确定测试用例的颗粒度?测试用例过于粗糙,可能无法全面覆盖系统的细节;而颗粒度过细,又会导致测试重复、冗余。掌握合适的颗粒度,不仅可以提高测…

【C++】深入解析二维数组初始化与越界问题

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯问题代码背景问题现象 💯初步分析与发现的问题1. 二维数组的初始化问题补充说明 2. 数组越界访问为什么数组越界问题没有直接报错? 💯解…

Unity性能优化总结

目录 前言 移动端常见性能优化指标​编辑 包体大小优化 FPS CPU占用率 GPU占用率 内存 发热和耗电量 流量优化 前言 终于有时间了,我将在最近两个项目中进行优化的一些经验进行归纳总结以飨读者。因为我习惯用思维导图,所以归纳的内容主要以图来…

用QT实现 端口扫描工具1

安装在线QT,尽量是完整地自己进行安装,不然会少包 参考【保姆级图文教程】QT下载、安装、入门、配置VS Qt环境-CSDN博客 临时存储空间不够。 Windows系统通常会使用C盘来存储临时文件。 修改临时文件存储位置 打开系统属性: 右键点击“此电…

鸿蒙HarmonyOS开发:基于Swiper组件和自定义指示器实现多图片进度条轮播功能

文章目录 一、概述1、场景介绍2、技术选型 二、实现方案1、图片区域实现2、底部导航点设计3、手动切换 三、所有代码1、设置沉浸式2、外层Tabs效果3、ImageSwiper组件 四、效果展示 一、概述 在短视频平台上,经常可以见到多图片合集。它的特点是:由多张…

【JVM】总结篇-类的加载篇之 类的加载器 和ClassLoader分析

文章目录 类的加载器ClassLoader自定义类加载器双亲委派机制概念源码分析优势劣势如何打破Tomcat 沙箱安全机制JDK9 双亲委派机制变化 类的加载器 获得当前类的ClassLoader clazz.getClassLoader() 获得当前线程上下文的ClassLoader Thread.currentThread().getContextClassLoa…

nginx学习之路-nginx配置https服务器

文章目录 1. 生成证书2. 配置证书1. 拷贝证书文件2. 修改conf/nginx.conf文件内容 3. 查看效果1. 重载配置2. 访问 1. 生成证书 在linux系统下执行,使用openssl命令。(windows环境也可以使用cmder) # 1. 生成私钥 server2025.key(无密码保护…

鸿蒙应用开发搬砖经验之—使用DevTools工具调试前端页面

环境说明: 系统环境:Mac mini M2 14.5 (23F79) 开发IDE:DevEco Studio 5.0.1 Release 配置步骤: 按着官方的指引来慢慢一步一步来,但前提是要配置好SDK的路径(没有配置的话,可能先看下面的配…

【NLP高频面题 - 分布式训练篇】ZeRO主要为了解决什么问题?

【NLP高频面题 - 分布式训练篇】ZeRO主要为了解决什么问题? 重要性:★★ 零冗余优化器技术由 DeepSpeed 代码库提出,主要用于解决数据并行中的模型冗余问题,即每张 GPU 均需要复制一份模型参数。 ZeRO的全称是Zero Redundancy …

《探秘计算机视觉与深度学习:开启智能视觉新时代》

《探秘计算机视觉与深度学习:开启智能视觉新时代》 一、追溯起源:从萌芽到崭露头角二、核心技术:解锁智能视觉的密码(一)卷积神经网络(CNN):图像识别的利器(二&#xff0…

[paddle] 非线性拟合问题的训练

利用paddlepaddle建立神经网络,模拟有限个数据的非线性拟合 本文仍然考虑 f ( x ) sin ⁡ ( x ) x f(x)\frac{\sin(x)}{x} f(x)xsin(x)​ 函数在区间 [-10,10] 上固定数据的拟合。 import paddle import paddle.nn as nn import numpy as np import matplotlib.…

详解GPT-信息抽取任务 (GPT-3 FAMILY LARGE LANGUAGE MODELS)

GPT-3 FAMILY LARGE LANGUAGE MODELS Information Extraction 自然语言处理信息提取任务(NLP-IE):从非结构化文本数据中提取结构化数据,例如提取实体、关系和事件 [164]。将非结构化文本数据转换为结构化数据可以实现高效的数据处…

逆向入门(2)C篇-基础知识

C基础 1、在C中,函数的变量是从右往左传递的,也就是test(x,y),先传入y,再传x。 2、变量的分类: (1)全局变量。在编译的时候就已经确定了内存地址和宽度,变量名就是内存地址的别名…

服务器数据恢复—离线盘数超过热备盘数导致raidz阵列崩溃的数据恢复

服务器数据恢复环境&故障: 一台配有32块硬盘的服务器在运行过程中突然崩溃不可用。经过初步检测,基本上确定服务器硬件不存在物理故障。管理员重启服务器后问题依旧。需要恢复该服务器中的数据。 服务器数据恢复环境: 1、将服务器中硬盘…

Echart实现3D饼图示例

在可视化项目中,很多地方会遇见图表;echart是最常见的;这个示例就是用Echart, echart-gl实现3D饼图效果,复制即可用 //需要安装,再引用依赖import * as echarts from "echarts"; import echar…

PostgreSQL学习笔记(一):PostgreSQL介绍和安装

目录 概念 PostgreSQL简介 PostgreSQL的关键特性 1. 标准兼容性 2. 扩展性 3. 数据完整性和可靠性 4. 丰富的数据类型 5. 查询能力 6. 事务和并发控制 7. 扩展和插件 8. 跨平台和多语言支持 9. 高可用性和扩展性 常用场景 安装 Linux apt安装 下载安装包安装 客…