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

闲聊ARM内核参数传递机制

之前一直没怎么在意这个问题,直到最近搞了个奇奇怪怪的项目,才发现这部分知识得补上来,记录一下。

ARM有一个标准,叫《Procedure Call Standard for the Arm Architecture》,人话就是ARM架构过程调用标准,它的目标就是为不同编译器生成的代码提供了统一的调用规范,使得单独编译的C程序和汇编程序能够相互调用。

文章里详细说明了寄存器的分类:R0-R3用于参数传递(调用者保存寄存器),R4-R11用于保存局部变量(被调用者保存寄存器),解决了函数调用过程中寄存器值可能被意外覆盖的问题。

同时比较关键也是今天主题,就是参数传递机制的统一,它规定了函数的前四个参数通过寄存器传递,超出部分使用栈传递,返回值通过R0返回。这种标准化避免了不同编译器采用不同传递方式导致的兼容性问题。特别提到在64位架构中,寄存器数量增加到31个,可以支持8个参数通过寄存器传递。

那我们来看看具体示例,以M4为例。

首先定义函数,分别涉及到传2个参数,传5个参数,传结构体,传结构体指针,如下:

 然后来看汇编,

(1)AddTest1,仅传递2个参数,根据规则当然应该直接用寄存器即可,汇编代码如下:

代码首先将参数存放到寄存器R0和R1中, 然后跳到AddTest,该函数的汇编代码如下:

也符合规范里使用R0作为返回值的要求。

(2)AddTest2,传递5个参数,按照规范前4个参数使用寄存器R0-R3,汇编代码如下:

代码首先将第5个参数压到栈里,对应地址0x1ffE4290,然后就其余四个参数放到寄存器R0-R4里,最后跳到函数里执行,具体代码如下:

首先是把R4压栈,保护现场,然后使用R4作为中间寄存器来存放栈里的第5个参数,最后分别加R0-R4,最后以R0承接返回值,如下:

(3)我们再来看看直接传结构体是什么情况,汇编如下:

 这里就需要注意了,首先我们在main里定义了结构体add_type addStruct = {1,2,3},本身就存在栈里,如下:

因此,第一步就是要从栈里把数据取出来,由于该结构体只有三个参数,所以还是用寄存器传递的方式,如下:

在函数里就直接使用寄存器进行相加即可,

 那如果是传递的结构体超过了4个参数,举一反三即可。 

(4)如果是传递指针 ,情况又不太一样,我们来看汇编。

代码直接就该结构体对应的栈地址作为参数通过R0传递过去, 在该函数内部取栈里取数据,如下:

好了,奇奇怪怪的知识又增加了。了解这个有什么用呢,或许大概MCU里有一套固件API,不想和调用者共用栈,以免泄露信息,知道传参的逻辑,才能在固件API运行时有正确的参数值。

相关文章:

  • 广州网站建设藤虎网络网络营销系统
  • 17.zwd一起做网站池尾站打开百度网站首页
  • wordpress自适应教程seo优化方向
  • 大气网站模板下载关键词词库
  • 页面设计师肇庆seo排名外包
  • 做网站卖狗挣钱吗营销公司排行
  • Harmony状态管理@Event
  • JVM的内存模型和内存结构
  • 【数字后端】- 什么是NDR规则?
  • Android检测当前进程或者应用是否被调试
  • android脱糖
  • 深度解析torchrun与local_rank
  • NIPS-2001《Partially labeled classification with Markov random walks》
  • 收银机安装飞牛NAS自动息屏方案
  • 程序猿成长之路之数据挖掘篇——聚类算法介绍
  • 01-StarRocks安装部署FAQ
  • 2025年渗透测试面试题总结-2025年HW(护网面试) 10(题目+回答)
  • linux grep的一些坑
  • (3)ROS2:6-dof前馈+PD / 阻抗控制器
  • 交易期权先从买方开始
  • 【AI大模型】Spring AI 基于Redis实现对话持久存储详解
  • 华为云对象存储OBS 支持安卓/iOS/鸿蒙UTS组件
  • SQL Server 查询数据库及数据文件大小
  • 工作流会使用到Webhook是什么
  • 爬取小红书相关数据导入到excel
  • C++ 第二阶段:运算符重载 - 第二节:重载与 const 成员函数