当前位置: 首页 > news >正文

Linux-C-函数栈-SP寄存器

 sp(Stack Pointer,栈指针)是计算机体系结构中一个非常重要的寄存器,下面将详细介绍其作用和原理

作用

1. 管理栈内存

栈是一种后进先出(LIFO,Last In First Out)的数据结构,在程序运行过程中,栈用于存储局部变量、函数调用的上下文信息(如返回地址、寄存器值等)。sp 寄存器的主要作用就是指向栈顶的位置,通过移动 sp 指针,可以在栈上进行数据的压入(PUSH)和弹出(POP)操作。

2. 支持函数调用

当程序调用一个函数时,需要保存当前的执行上下文(如返回地址、寄存器的值等),以便在函数执行完毕后能够正确返回并恢复现场。这些信息通常会被压入栈中,sp 指针会相应地移动来指示栈顶的新位置。在函数返回时,再从栈中弹出这些信息,sp 指针也会恢复到调用函数之前的位置。

3. 存储局部变量

函数内部定义的局部变量通常也存储在栈上。在函数执行过程中,sp 指针会根据局部变量的大小进行调整,为局部变量分配栈空间。当函数执行完毕后,sp 指针会恢复到原来的位置,释放这些局部变量所占用的栈空间。

原理

1. 栈的生长方向

栈的生长方向在不同的体系结构中可能有所不同,常见的有两种:向下生长(向低地址方向)和向上生长(向高地址方向)。

  • 向下生长:大多数现代计算机体系结构(如 ARM、x86 等)采用向下生长的栈。在这种情况下,栈底位于较高的地址,栈顶位于较低的地址。当向栈中压入数据时,sp 指针的值会减小;当从栈中弹出数据时,sp 指针的值会增大。

  • 向上生长:少数体系结构采用向上生长的栈,栈底位于较低的地址,栈顶位于较高的地址。此时,压入数据时 sp 指针的值会增大,弹出数据时 sp 指针的值会减小。

2. 压栈和出栈操作

以向下生长的栈为例,介绍压栈和出栈操作的原理。

  • 压栈操作(PUSH):当需要将数据压入栈中时,首先将 sp 指针的值减去数据的大小,然后将数据存储到 sp 指针所指向的内存地址。例如,在 ARM 汇编中,使用 PUSH 指令将寄存器的值压入栈中:

 PUSH {r0, r1} ; 将寄存器 r0 和 r1 的值压入栈中

执行该指令时,sp 指针会自动减去 8(假设每个寄存器为 4 字节),然后将 r0 和 r1 的值依次存储到 sp 指针所指向的内存地址。 

  • 出栈操作(POP):当需要从栈中弹出数据时,首先将 sp 指针所指向的内存地址中的数据读取到目标寄存器中,然后将 sp 指针的值加上数据的大小。例如,在 ARM 汇编中,使用 POP 指令从栈中弹出数据:
POP {r0, r1}  ; 从栈中弹出数据到寄存器 r0 和 r1

执行该指令时,首先将 sp 指针所指向的内存地址中的数据读取到 r0 中,然后将 sp 指针的值加上 4,再将新的 sp 指针所指向的内存地址中的数据读取到 r1 中,最后 sp 指针的值再加上 4。 

3. 函数调用和返回过程

函数调用和返回过程涉及到栈指针的一系列操作,以确保程序能够正确执行。

  • 函数调用:当程序调用一个函数时,通常会执行以下步骤:

    1. 将返回地址压入栈中,以便函数执行完毕后能够返回到调用点。
    2. 保存当前的寄存器值(如果需要)到栈中。
    3. 调整 sp 指针,为函数的局部变量分配栈空间。
    4. 跳转到被调用函数的入口地址开始执行。
  • 函数返回:当函数执行完毕后,会执行以下步骤:

    1. 恢复之前保存的寄存器值(如果有)。
    2. 从栈中弹出返回地址。
    3. 调整 sp 指针,释放函数的局部变量所占用的栈空间。
    4. 跳转到返回地址继续执行。
  • 示例代码(ARM 汇编)

     
        .global mainmain:; 保存返回地址和寄存器值PUSH {lr}; 为局部变量分配栈空间SUB sp, sp, #4; 假设局部变量赋值MOV r0, #10STR r0, [sp]; 恢复栈空间ADD sp, sp, #4; 恢复返回地址并返回POP {pc}
    
     

    在这个示例中,PUSH {lr} 将返回地址压入栈中,SUB sp, sp, #4 为局部变量分配 4 字节的栈空间,ADD sp, sp, #4 释放局部变量所占用的栈空间,POP {pc} 从栈中弹出返回地址并跳转到该地址继续执行。

  • sp 寄存器是管理栈内存的关键,通过移动 sp 指针可以实现数据的压栈和出栈操作,支持函数调用和局部变量的存储。理解 sp 指针的作用和原理对于深入理解程序的执行过程和内存管理非常重要。

相关文章:

Linux-C-函数栈-SP寄存器

sp(Stack Pointer,栈指针)是计算机体系结构中一个非常重要的寄存器,下面将详细介绍其作用和原理。 作用 1. 管理栈内存 栈是一种后进先出(LIFO,Last In First Out)的数据结构,在程…...

vi的基本使用

vi 是 Unix/Linux 系统中最常用的文本编辑器之一,功能强大但学习曲线较陡。以下是 vi 的基本使用方法: --- ### **1. vi 的两种模式** - **命令模式(Command Mode)**: - 默认进入的模式,用于执行命令&a…...

clickhouse--表引擎的使用

表引擎决定了如何存储表的数据。包括: 数据的存储方式和位置,写到哪里以及从哪里读取数据。(默认是在安装路径下的 data 路径)支持哪些查询以及如何支持。(有些语法只有在特定的引擎下才能用)并发数据访问。索引的使用&#xff0…...

LeetCode刷题零碎知识点整理

系列博客目录 文章目录 系列博客目录 数组变量有length属性&#xff0c;String类的对象有length()方法。String s; s.split("\\s");不能去除头部空格&#xff0c;需要使用s s.trim();String类的对象有toCharArray()方法&#xff0c;List<>类型有toArray()方法…...

GLTFLoader.js和OrbitControls.js两个 JavaScript 文件都是 Three.js 生态系统中的重要组成部分

GLTFLoader.js和OrbitControls.js两个 JavaScript 文件都是 Three.js 生态系统中的重要组成部分&#xff1a; 1. GLTFLoader.js 作用 GLTFLoader.js 是 Three.js 库中的一个辅助加载器脚本&#xff0c;其主要功能是加载 GLB 或 GLTF 格式的 3D 模型。GLTF&#xff08;GL Tra…...

大厂数据仓库数仓建模面试题及参考答案

目录 什么是数据仓库,和数据库有什么区别? 数据仓库的基本原理是什么? 数据仓库架构是怎样的? 数据仓库分层(层级划分),每层做什么?分层的好处是什么?数据分层是根据什么?数仓分层的原则与思路是什么? 数仓建模常用模型有哪些?区别、优缺点是什么?星型模型和雪…...

angular简易计算器

说明&#xff1a; 用angular实现计算器效果&#xff0c;ui风格为暗黑 效果图&#xff1a; step1: C:\Users\Administrator\WebstormProjects\untitled4\src\app\calnum\calnum.component.ts import { Component } from angular/core;Component({selector: app-calnum,import…...

谈谈 ES 6.8 到 7.10 的功能变迁(3)- 查询方法篇

上一篇咱们了解了 ES 7.10 相较于 ES 6.8 新增的字段类型&#xff0c;这一篇我们继续了解新增的查询方法。 Interval 间隔查询&#xff1a; 功能介绍 Interval 查询&#xff0c;词项间距查询&#xff0c;可以根据匹配词项的顺序、间距和接近度对文档进行排名。主要解决的查询…...

16、Python面试题解析:python中的浅拷贝和深拷贝

在 Python 中&#xff0c;浅拷贝&#xff08;Shallow Copy&#xff09; 和 深拷贝&#xff08;Deep Copy&#xff09; 是处理对象复制的两种重要机制&#xff0c;它们的区别主要体现在对嵌套对象的处理方式上。以下是详细解析&#xff1a; 1. 浅拷贝&#xff08;Shallow Copy&a…...

游戏引擎学习第119天

仓库:https://gitee.com/mrxiao_com/2d_game_3 上一集回顾和今天的议程 如果你们还记得昨天的进展&#xff0c;我们刚刚完成了优化工作&#xff0c;目标是让某个程序能够尽可能快速地运行。我觉得现在可以说它已经快速运行了。虽然可能还没有达到最快的速度&#xff0c;但我们…...

爬虫解析库:Beautiful Soup的详细使用

文章目录 1. 安装 Beautiful Soup2. 基本用法3. 选择元素4. 提取数据5. 遍历元素6. 修改元素7. 搜索元素8. 结合 requests 使用9. 示例&#xff1a;抓取并解析网页10. 注意事项 Beautiful Soup 是一个用于解析 HTML 和 XML 文档的 Python 库&#xff0c;它提供了简单易用的 API…...

OpenHarmony-4.基于dayu800 GPIO 实践(2)

基于dayu800 GPIO 进行开发 1.DAYU800开发板硬件接口 LicheePi 4A 板载 2x10pin 插针&#xff0c;其中有 16 个原生 IO&#xff0c;包括 6 个普通 IO&#xff0c;3 对串口&#xff0c;一个 SPI。TH1520 SOC 具有4个GPIO bank&#xff0c;每个bank最大有32个IO&#xff1a;  …...

【C++设计模式】观察者模式(1/2):从基础到优化实现

1. 引言 在 C 软件与设计系列课程中&#xff0c;观察者模式是一个重要的设计模式。本系列课程旨在深入探讨该模式的实现与优化。在之前的课程里&#xff0c;我们已对观察者模式有了初步认识&#xff0c;本次将在前两次课程的基础上&#xff0c;进一步深入研究&#xff0c;着重…...

《机器学习数学基础》补充资料:欧几里得空间的推广

在《机器学习数学基础》第 1 章介绍了向量空间&#xff0c;并且说明了机器学习问题通常是在欧几里得空间。然而&#xff0c;随着机器学习技术的发展&#xff0c;特别是 AI 技术开始应用于科学研究中&#xff0c;必然会涉及到其他类型的空间。本文即在《机器学习数学基础》一书所…...

在配置PX4中出现的问题2

想要原教程的请看&#xff1a;第一次配置中出现的问题 前面一切正常&#xff08;gazebo导入models那一步在刚刚解压好的文件夹里就删不掉stereo_camera等文件&#xff0c;ls打开也看不到&#xff0c;应该时我下的包里面本来就没有&#xff09;&#xff0c;到 make px4_sitl_def…...

2025-2-24-4.9 单调栈与单调队列(基础题)

文章目录 4.9 单调栈与单调队列&#xff08;基础题&#xff09;单调栈739. 每日温度42. 接雨水单调队列239. 滑动窗口最大值 4.9 单调栈与单调队列&#xff08;基础题&#xff09; 很有趣的两个数据结构。 原视频讲解链接 单调栈 739. 每日温度 题目链接 给定一个整数数组 te…...

python绘图之swarmplot分布散点图

swarmplot 是 Seaborn 提供的一种用于展示分类数据分布的散点图。它的主要作用是将数据点按照分类变量&#xff08;通常是离散变量&#xff09;进行分组&#xff0c;并在每个分类中以一种非重叠的方式展示数据点的位置。这种可视化方式可以帮助我们直观地理解数据在不同分类下的…...

数据库之MySQL——事务(一)

1、MySQL之事务的四大特性(ACID)&#xff1f; 原子性(atomicity)&#xff1a;一个事务必须视为一个不可分割的最小工作单元&#xff0c;整个事务中的所有操作要么全部提交成功&#xff0c;要么全部失败回滚&#xff0c;对于一个事务来说&#xff0c;不可能只执行其中的一部分操…...

Linux学习笔记之文件

1.文件 1.1文件属性 当我们创建文件时&#xff0c;文件就有了对应的属性&#xff0c;可以用mkdir创建目录&#xff0c;touch创建普通文件。用ls -al查看文件属性。 从上图可以看出目录或者文件的所有者&#xff0c;所属组&#xff0c;其他人权限&#xff0c;创建时间等信息。由…...

LLM学习

1、基础概念篇 大模型训练三部曲Pretraining SFT RLHF...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...