RISC-V 的寄存器分为以下几类:
临时寄存器:t0-t6(x5-x7, x28-x31)
保存寄存器:s0-s11(x8, x9, x18-x27)
参数寄存器:a0-a7(x10-x17)
返回地址寄存器:ra(x1) 注意:不是返回值,call函数的时候的下一条指令
栈指针寄存器:sp(x2)
全局指针寄存器:gp(x3)
线程指针寄存器:tp(x4)
参数传递
前8个参数:通过参数寄存器 a0-a7 传递。
超过8个参数:通过栈传递,超出的参数会依次压入栈中。
返回值
返回值:使用寄存器 a0 和 a1 返回。如果返回值超过两个寄存器的大小,则通过栈传递。
栈帧布局
每个函数调用都会创建一个新的栈帧,栈帧的布局如下:
返回地址:保存调用者的返回地址。
保存寄存器:保存被调用函数使用的保存寄存器。
局部变量和临时数据:函数的局部变量和临时数据。
调用者保存和被调用者保存
调用者保存(Caller-saved):临时寄存器(t0-t6)和参数寄存器(a0-a7)。调用函数前,调用者需要保存这些寄存器的值。
被调用者保存(Callee-saved):保存寄存器(s0-s11)和返回地址寄存器(ra)。被调用函数需要保存和恢复这些寄存器的值。
# 调用者函数
caller_function:
# 保存调用者保存寄存器
addi sp, sp, -16
sd ra, 8(sp)
sd t0, 0(sp)
# 设置参数并调用被调用者函数
li a0, 5
li a1, 10
call callee_function
# 恢复调用者保存寄存器
ld t0, 0(sp)
ld ra, 8(sp)
addi sp, sp, 16
ret
# 被调用者函数
callee_function:
# 保存被调用者保存寄存器
addi sp, sp, -16
sd s0, 0(sp)
# 函数体
add s0, a0, a1 # s0 = a0 + a1
# 恢复被调用者保存寄存器
ld s0, 0(sp)
addi sp, sp, 16
ret
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。