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

putao
5 声望0 粉丝

推动世界向前发展,改善民生。