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

80、【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:栈空间对齐

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

接之前 blog
【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:栈指针和帧指针(上)
【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:栈指针和帧指针(下)
【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:r7 寄存器

分析了栈指针和帧指针的一些概念,并演示了栈帧的操作,并解释了为什么选择 r7 寄存器作为帧指针,下面最后再补充点细节

栈空间对齐

首先来回顾下栈空间操作的主要流程
在这里插入图片描述

  • 调用 push {r7, lr} 保存当前的帧指针(R7)和链接寄存器(LR),进入新的函数(main)时,需要保存旧的帧指针和返回地址,方便函数执行完后可以正确恢复现场并返回到调用者
  • 通过 sub sp, sp, #8 指令来减少栈指针的值,实际上是向栈上申请了 8 个字节的空间,这个空间可以用来存储局部变量或者作为临时存储区域,这里的 8 字节是根据函数内部需要保留的数据量来决定,后面会详细讨论这个
  • 在函数结尾,通过 adds r7, r7, #8 和 mov sp, r7 来释放之前分配的栈空间,并通过 pop {r7, pc} 恢复先前保存的 r7 寄存器状态,返回控制权到调用者

这里面有个细节,就是 sub sp, sp, #8 指令,这条指令向栈空间上申请了 8 个字节,下面来看下源码
在这里插入图片描述
在 main 函数这里,只有一个局部变量 c,在 32 位系统中,理论上只需要 4 个字节的空间,但是却分配了 8 字节空间,这里就涉及到了栈空间对齐,下面看下 AAPCS32 中对 栈空间对齐的官方描述

在这里插入图片描述

  • Universal stack constraints:所有时间点都必须满足栈指针 4 字节对齐(SP mod 4 == 0)
  • Stack constraints at a public interface:在函数调用入口处,还必须额外满足 8 字节对齐(SP mod 8 == 0)

下面再回过头来看刚才的栈空间操作流程,从对齐的视角来分析
在这里插入图片描述

  • 首先将 r7,lr 进行压栈,r7 和 lr 分别占用两个 4 字节,所以 SP 这里减了一个 8 字节
  • 由于只有一个 int 类型的局部变量,本来申请一个 4 字节空间足矣,但是必须要进行 8 字节对齐,所以这里 sub sp, sp, #8 申请了 8 字节空间

同样的,从对齐的视角,再来看 add_func
在这里插入图片描述

  • 首先将 lr 进行压栈(r7 不用压栈,之前的 blog 【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:叶子函数 有分析原因),lr 占 4 字节,所以 SP 减了 4 字节空间
  • 申请栈空间时,首先 add_func 里面有两个局部变量 a 和 b 需要存储,a 和 b 都是 int 类型的,都占 4 字节,加起来 8 字节,本来申请 8 字节空间足矣,但是前面压栈时,只压了 4 字节,4 + 8 = 12 字节,还未对齐到 8 字节空间,所以这里需对齐到 12 字节,4 + 12 = 16,所以指令 sub sp, sp, #12 向栈空间上申请了 12 字节内存

先分析到这里,下篇 blog 继续

http://www.dtcms.com/a/288475.html

相关文章:

  • kubeadm方式部署Kubernetes v1.22.2集群
  • 零基础学习性能测试第二章-linux服务器监控:磁盘监控
  • 如何设计一个高效的网页爬虫?
  • 7月19日 暴雨蓝色预警:全国多地迎强降雨,需防范次生灾害
  • Linux练习二
  • 信息系统风险的安全技术防范思路
  • 零基础学习性能测试第二章-linux服务器监控:CPU监控
  • [每日随题10] DP - 重链剖分 - 状压DP
  • stm32继电器使用方法
  • Java并发7--FutrureTask 及CompletetableFuture
  • 高速SAR架构ADC选型设计
  • 为什么选择PGCE中级认证?
  • startnet.cmd命令里面的factory -minint
  • 零基础学习性能测试第二章-监控体系
  • 多线程 示例
  • QML 动画效果详解
  • Public Key Retrieval is not allowed
  • CS231n-2017 Lecture3线性分类器、最优化笔记
  • 测试计划(抽奖系统)
  • DC-DC降压转换5.5V/3A高效率低静态同步降压转换具有自适应关断功能
  • CCF编程能力等级认证GESP—C++7级—20250628
  • Navicat 查看单张表建表ddl
  • Python观察者模式详解:从理论到实战
  • 142. 环形链表 II
  • Spring IOC容器在Web环境中是如何启动的(源码级剖析)?
  • MCP 协议详细分析 二 Sampling
  • Jmeter的元件使用介绍:(一)测试计划详解
  • string的增删改查模拟实现(简单版)【C++】
  • 数据分析综合应用 30分钟精通计划
  • 使用UV管理FastAPI项目