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加回与函数开始时相同的值。

根据调用者保存寄存器和被调用者保存寄存器的定义,我们可以得知: - 调用者保存寄存器是指在调用函数之前,调用者将需要用到的寄存器保存起来,以便在函数调用之后回复这些寄存器。 - 被调用者保存寄存器是指在函数使用的寄存器需要被保存,以便在函数返回时恢复这些寄存器。 因此,在这个问题,如果编译器可以确定变量a、b和c在某个点不再被使用,那么编译器应该选择调用者保存寄存器保存这些寄存器变量。这是因为如果使用被调用者保存寄存器,当函数fn2(b)被递归调用时,寄存器b的将被保存恢复,即使它可能不会在fn2(b)使用。这将导致额外的开销和性能损失。 为了证明这个答案,我们可以考虑以下伪代码: ``` fn1() { // 在调用之前保存调用者保存寄存器 save_registers(); // 使用寄存器a、b和c a = ... b = ... c = ... // 当变量a、b和c不再使用时,可以选择调用者保存寄存器 // 来保存这些寄存器变量 // 因为函数fn2(b)可能会递归多次调用自己,如果使用被调用者保存寄存器, // 寄存器b的将被保存恢复,即使它可能不会在fn2(b)使用 fn2(b); // 在返回之前恢复调用者保存寄存器 restore_registers(); } fn2(b) { // 在调用之前保存被调用者保存寄存器 save_registers(); // 使用寄存器b ... // 在返回之前恢复被调用者保存寄存器 restore_registers(); } ``` 如果我们使用调用者保存寄存器保存寄存器变量a、b和c,那么在函数fn2(b)被调用时,只有调用者保存寄存器保存恢复。这将导致更少的开销和更好的性能。 因此,在这个问题,编译器应该在调用者保存寄存器和被调用者保存寄存器之间选择调用者保存寄存器保存寄存器变量a、b和c。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

D了一天bug忘了编译

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值