RISC-V基础之函数调用(一)简单的函数调用(包含实例)

高级语言支持函数(也称为过程或子程序)来重用通用的代码,以及使程序更加模块化和可读。函数可以有输入,称为参数,和输出,称为返回值。函数应该计算返回值,并且不产生其他意外的副作用。

在一个函数调用另一个函数时,调用者(caller)和被调用者(callee)必须约定好在哪里放置参数和返回值。在RISC-V程序中,惯例是调用者在进行函数调用前将最多八个参数放在寄存器a0到a7中,而被调用者在完成前将返回值放在寄存器a0中。遵循这个惯例,两个函数都知道在哪里找到参数和返回值,即使调用者和被调用者是由不同的人编写的。

被调用者不能干扰调用者的行为。这意味着被调用者必须知道在完成后返回到哪里,而且不能破坏调用者需要的任何寄存器或内存。调用者在使用跳转并链接(jump and link)指令(jal)跳转到被调用者时,同时将返回地址存储在返回地址寄存器ra中。被调用者不能覆盖任何架构状态或内存,因为这些是调用者依赖的。具体来说,被调用者必须保持保存寄存器(s0−s11)、返回地址(ra)和堆栈(一部分内存用于临时变量)不变。

如上实例:

上图展示了主函数(main)调用简单函数(simple)的过程。main是调用者,simple是被调用者。simple函数没有输入参数,也没有返回值,它只是返回给调用者。在 Example中,每条RISC-V指令的左边给出了示例指令地址。jal和jr ra是函数调用和返回所必需的两条指令。主函数通过执行jal simple来调用simple函数,这个指令做了两件事:它跳转到目标指令的地址,即simple所在的地址(0x0000051C),并且把返回地址,即jal后面的指令的地址(在这个例子中是0x00000304)存储在返回地址寄存器(ra)中。程序员可以指定哪个寄存器被写入返回地址,但默认是ra。simple函数立即通过执行jr ra来返回,这个指令跳转到ra寄存器中保存的指令地址。主函数然后继续在这个地址(0x00000304)执行

RISC-V的约定是,函数使用a0到a7这八个寄存器来传递输入参数,其中a0是最左边的参数,a7是最右边的参数。函数使用a0寄存器来返回输出值。如果函数有多于八个的输入参数,那么多余的参数会被放在栈上。

上例展示了一个名为diffofsums的函数,它接收四个输入参数,并返回一个输出值。result是一个局部变量,我们选择把它保存在s3寄存器中。

根据RISC-V的约定,调用函数(main)在调用被调用函数(diffofsums)之前,把函数参数从左到右放入输入寄存器a0到a7中。被调用函数(diffofsums)把返回值存储在返回寄存器a0中。当函数返回时,调用函数(main)可以从a0中读取返回值。

相关推荐
若风的雨3 天前
RISC-V入门资料
risc-v
禾仔仔5 天前
RISC-V CLINT、PLIC及芯来ECLIC中断机制分析 —— RISC-V中断机制(一)
risc-v·plic·eclic·clic·clint·中断咬尾·中断嵌套
ssslar5 天前
MIT XV6 - 1.6 Lab: Xv6 and Unix utilities -uptime
操作系统·risc-v·xv6
Thomas_Fly6 天前
RISC-V hardfault分析工具,RTTHREAD-RVBACKTRACE
risc-v
sinovoip10 天前
Banana Pi BPI-CM6 是一款八核 RISC-V 模块,兼容 Raspberry Pi CM 载板
risc-v
ssslar11 天前
MIT XV6 - 1.2 Lab: Xv6 and Unix utilities - pingpong
操作系统·risc-v·xv6
乌旭14 天前
算力经济模型研究:从云计算定价到去中心化算力市场设计
人工智能·深度学习·云计算·去中心化·区块链·gpu算力·risc-v
乌旭16 天前
RISC-V GPU架构研究进展:在深度学习推理场景的可行性验证
人工智能·深度学习·架构·transformer·边缘计算·gpu算力·risc-v
ssslar18 天前
MIT XV6 - 1.1 Lab: Xv6 and Unix utilities - sleep 是怎样练成的?
操作系统·risc-v·xv6
黑不拉几的小白兔19 天前
risc-V学习日记(4):RV32I指令集
学习·risc-v