RISC-V基础之函数调用(三)保留寄存器(包含实例)

RISC-V将寄存器分为保留和非保留两类。保留寄存器是指在函数调用前后必须保持相同值的寄存器,因为调用者期望在调用后能够继续使用这些寄存器的值。保留寄存器包括s0到s11(因此称为saved),sp和ra。非保留寄存器,也称为临时寄存器,是指在函数调用中可以自由修改的寄存器,不需要保存和恢复。非保留寄存器包括t0到t6(因此称为temporary)和a0到a7,即参数寄存器。

函数调用时,如果一个函数需要修改保留寄存器的值,那么它必须在修改前将它们保存到堆栈上,并在返回前将它们从堆栈上恢复。这样可以避免破坏调用者的寄存器内容。而如果一个函数只修改非保留寄存器的值,那么它就不需要保存和恢复它们,因为调用者不会再使用它们。

上述代码示例假设所有使用的寄存器(t0,t1和s3)都必须保存和恢复。但是如果调用者没有使用这些寄存器,那么保存和恢复它们就是浪费时间和空间。为了避免这种浪费,如下展示了一个更优化的版本的diffofsums函数,它只保存了s3到堆栈上。t0和t1是非保留寄存器,所以不需要保存。

如果一个函数需要修改保留寄存器的值,那么它必须在修改前将它们保存到堆栈上,并在返回前将它们从堆栈上恢复。这样可以避免破坏调用者的寄存器内容。而如果一个函数只修改非保留寄存器的值,那么它就不需要保存和恢复它们,因为调用者不会再使用它们。

下表总结了哪些寄存器是保留的。一般来说,s0到s11用于存储函数内部的局部变量,所以它们必须被保存。ra也必须被保存,因为它记录了返回地址。t0到t6用于存储临时结果。这些计算通常在函数调用前完成,所以它们不需要被保存,并且很少有情况下调用者需要保存它们。a0到a7经常在函数调用过程中被覆盖。因此,如果调用者在被调用函数返回后还依赖于自己的某些参数,那么它们必须被保存。

更详细的说明可参考操作系统基础知识介绍之指令集体系结构:RISC-V寄存器(掺杂与ARM和X86部分比对)_操作系统的指令集_管二狗赶快去工作!的博客-CSDN博客

堆栈指针sp以上的堆栈空间是自动保留的,只要被调用者不写入sp以上的内存地址。这样可以避免修改其他函数的堆栈帧。堆栈指针本身也是保留的,因为被调用者在返回前会释放自己分配的堆栈帧,即将sp加回与函数开始时相同的值。

相关推荐
驱动探索者2 天前
RISC-V Local Interrupt 深度解析:从 CLINT 到 CLIC,再到 Zephyr 驱动实现
risc-v
weixin_727535623 天前
计算机组成原理:从晶体管到你面前这块屏幕的史诗之旅
risc-v
hongmai6668886 天前
ESP32-C61-WROOM-1-N8R2:Wi-Fi 6与RISC-V融合的中坚力量
人工智能·单片机·嵌入式硬件·物联网·智能家居·risc-v
国科安芯7 天前
在轨能源中枢:AS32S601型抗辐射MCU在卫星电源管理与配电系统中的控制策略研究
嵌入式硬件·架构·能源·risc-v·sps·电源管理·卫星
nh752716 天前
(一)HPM自定义工程创建实操
单片机·risc-v·hpm·先楫
蓝速科技18 天前
蓝速科技 RISC-V+ 鸿蒙终端:一机多场景信创改造实效评测
科技·harmonyos·risc-v
MounRiver_Studio19 天前
RISC-V IDE MRS2调试秘籍(三):通过栈帧可视化模块定位栈溢出、栈内存非法篡改等运行时错误
mcu·risc-v·代码调试
MounRiver_Studio20 天前
RISC-V IDE MRS2调试秘籍(一):通过Memory内存导出对比,锁定隐性内存异常代码
mcu·调试技巧·risc-v·代码调试
蓝速科技24 天前
蓝速科技 RISC-V 鸿蒙信创终端全场景落地方案
科技·harmonyos·risc-v
国科安芯24 天前
ASC4T245S分组双向控制架构深度解析:独立DIR/OE控制、QFN16封装与混合方向总线桥接
单片机·嵌入式硬件·物联网·fpga开发·架构·risc-v