1900_野火FreeRTOS教程阅读补充材料_AAPCS
全部学习汇总: g_FreeRTOS: FreeRTOS学习笔记 (gitee.com)
关于上面这个堆栈空间的分布,教程中就是一张图基本带过了。那么,为什么要这么处理呢?其实这个有一个基本的标准依据,那就是AAPCS。
什么是AAPCS呢?就是ARM架构的进程调用标准,或者说是函数调用标准。
进程以及函数很多时候概念是统一不拆分的,在这个文档中把这两个词语的更加细致的区分点描述了一下。如果是Procedure,那么就是不带返回值的函数;function则是带有返回值的函数。
外部可见性针对机器语言、更高级的语言来说,区分方式是不相同的。前者是二进制目标文件层面的定义规定,而后者测试在系统层面或者应用层面对于语言的规定。
这里把整个平台上可能的数据类型的大小以及对齐的说明以表格的形式呈现了一下。在野火的教程中,解释为什么按照8个字节来对齐的时候说的是因为要支持浮点。这个说法看起来是不准确的,因为常用的float其实是占用4个字节,double才是8个字节。除此之外,还有64bit的整形等数据也是需要8个字节对齐的。
这里是我现在手里的野火的文档中的描述。
容器化向量的内容对大多数调用来说是不透明的,唯一明确的规定内容为内存布局与调用接口上不同寄存器间的映射关系。
这里介绍了复合类型。
- 聚合,在形式上比较典型的应该是C语言中的结构体。这里没有如此描述可能是考虑了C++ 的部分规范实现。
- 联合
- 数组
基本函数的调用,适用于无硬件浮点系统或者Thumb代码。
内核指令可以访问内核寄存器,而协处理器提供了可以用于特殊操作的附加寄存器。
这里,PC、LR、SP、SP等寄存器的概念描述全都给出来了。这也是OS教程中的一些考虑处理的寄存器。相比于野火的教程,这里把每一个寄存器的更细致的角色进行了描述。比如,有的寄存器是用于传递参数的,有的寄存器测试用来存储变量的。这里的变量是局部变量,后面的资料中看到了进一步的解释。除了这些内核寄存器外,还有一个CPSR寄存器是这个标准中涉及到的寄存器。
这里是对变量寄存器的一个介绍。
关于大于32bit的数据处理,采用寄存器组合的方式来实现。至于更加复杂的处理,涉及到的数据更多的时候,肯定得借助于内存做中转。
这是关于SP数值约束的描述,来源也是堆栈的地址对齐。
这是返回值的传递方式,基本的原则也是能用寄存器则用寄存器,不能再借助于内存通过指针传递。
参数传递通过量级概念模型来实现:
- 源代码中的参数向机器类型的转换;
- 转换后的机器类型,进一步形成参数列表。
另外一部分之前阅读中考虑到的问题,我找到了几份网络文章辅助理解。我的疑惑点在于LR在多次调用的时候的处理。
参考1: ARM 过程调用标准 AAPCS 以及堆栈使用-
参考2: Arm Cortex-M Developer Guide — Zephyr Project Documentation
其中,参考1是cortex A系列的,参考2是cortex M系列的。综合看,可以基本理解之前看文档时候的一些疑惑点。
还有一些细节信息可能得结合整个ARM的内核相关文档来深入了解一下,这里先暂且跳过了。