博客 / 詳情

返回

risc-v 函數調用規範

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
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.