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

73、【OS】【Nuttx】【启动】深入理解 caller-saved 和 callee-saved(上)

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

背景
接上篇 blog
【OS】【Nuttx】【启动】栈溢出保护:caller-saved 和 callee-saved
简单分析了下 r10 为什么能保存栈底地址,下面继续来分析下 caller-saved 和 callee-saved

caller-saved 和 callee-saved

首先是 cortex-m 的寄存器结构
在这里插入图片描述
用户手册《Arm Cortex-M4 Processor Technical Reference Manual》里虽然只提到了 R13(SP),R14(LR),R15(PC)作为特殊用途寄存器,R0-R12 没有特殊用途,作为通用寄存器使用,但实际上,在使用过程中,R0-R12 之间还是有显著差别的,这种差别来源于比如函数调用等过程中,R0-R12 寄存器之间的一些使用约定

之前 blog 【OS】【Nuttx】【启动】栈溢出保护:caller-saved 和 callee-saved 提到

  • r0–r3:作为临时寄存器,约定用来将参数值传递给被调用函数,或者从被调用函数中返回结果值
  • r4-r12:约定用来保存函数内的局部变量或者长期使用的中间值

首先从这种约定的使用方式,又衍生出两个概念:易失性寄存器(volatile registers)和非易失性寄存器(non-volatile registers),下面来看下这两个概念

(非)易失性存储器?

在讲易失性寄存器(volatile registers)和非易失性寄存器(non-volatile registers)之前,先要区分开易失性存储器(volatile memory)和非易失性存储器(non-volatile memory)

通常讨论易失性存储器(volatile memory)和非易失性存储器(non-volatile memory)时,主要是讲掉电是否丢失,这取决于存储器的介质

  • 非易失性存储器(non-volatile memory):比如 flash,rom,掉电后数据不会丢失
  • 易失性存储器(volatile memory):比如 ram,掉电后数据会丢失

对于存储器来说,这是硬件介质上导致的差别,而对于寄存器里的易失性概念,更多的是寄存器上的使用约定,比如在 arm 的 AAPCS(ARM Architecture Procedure Call Standard) 或 x86 的调用规范中,所以两个词的意思和语境完全不同,需要理解这一点

volatile register

【易失性寄存器】:这些寄存器的内容在函数调用过程中可能被破坏,有几个点是反复强调过的

  • 如果在一个函数里用了这些寄存器,并保存了某些值,然后调用了另一个子函数(比如 bl sub_function),那么等子函数执行完回来时,这些易失性寄存器的值可能就没了
  • 如果想保留这些易失性寄存器的值,就需要把它们保存到内存的栈上
  • 可以把这些寄存器看作是临时草稿纸,随时可能会被别人擦掉内容
  • 在 arm 上,常见的 volatile 寄存器,比如 r0–r3,可以用来传入参数和传出返回值等临时数据

示意图如下

在这里插入图片描述

non-volatile register

【非易失性寄存器】:这些寄存器的内容在函数调用过程中必须保持不变,这里需要正确理解保持不变的含义

  • 保持不变不是说在函数调用时,子程序不能使用这些寄存器,而是说如果子程序使用了这些寄存器并修改了它们的值,那子程序就需要负责在函数返回前,把这些寄存器恢复成原来的值
  • 可以把这些寄存器看作是私人笔记本,别人借走后,不能随便改里面的内容(如果改了,最后还笔记本的时候,要恢复原状,让人看不出用过的痕迹)
  • 在 arm 上,常见的 non-volatile 寄存器,比如 r4–r8,r10-r11,可以用来保存函数内的局部变量或者长期使用的中间值

具体过程看下面这个示意图

在这里插入图片描述
先分析到这,后面继续

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

相关文章:

  • TypeScript---泛型
  • C语言初阶3-函数
  • 翱翔的智慧之翼:Deepoc具身智能如何赋能巡检无人机“读懂”工业现场
  • 电脑开机显示器不亮是怎么回事 这有解决方法
  • 数据治理到底是什么?搞清这四件事,你就彻底明白了!
  • python的病例管理系统
  • 非栈上格式化字符串漏洞(BSS段上)
  • openbmc pldmd分析(event事件分析)
  • 项目开发日记
  • 《财税企业经营管理秘籍(一):行业适配的获客方式》
  • 电商系统高并发订单支付问题:队列、限流、容错全方位解决方案
  • JAVA JVM垃圾收集
  • 上半年净利预增66%-97%,高增长的赛力斯该咋看?
  • 解决Vue页面黑底红字遮罩层报错:Unknown promise rejection reason (webpack-internal)
  • Semi-Supervised Single-View 3D Reconstruction via Prototype Shape Priors
  • LDO选型
  • 手把手一起使用Miniforge3+mamba平替Anaconda(Win10)
  • 【web应用】若依框架中,使用Echarts导出报表为PDF文件
  • Linux中LVM逻辑卷扩容
  • 第七章 愿景05 莹姐画流程图
  • 企业采购成本越来越贵?根源在哪,数据怎么分析?
  • Linux操作系统从入门到实战:怎么查看,删除,更新本地的软件镜像源
  • Python 类型注解实战:`Optional` 与安全数据处理的艺术
  • 递归与树形结构在前端的应用
  • 林吉特危机下的技术革命:马来西亚金融系统升维作战手册
  • 【深度探究系列(5)】:前端开发打怪升级指南:从踩坑到封神的解决方案手册
  • U-Net网络学习笔记(1)
  • ARM单片机OTA解析(二)
  • cesium添加原生MVT矢量瓦片方案
  • 在 Spring Boot 中使用 WebMvcConfigurer