資料來源:NCKU Jserv 教授開設之計算機結構課程-RISC-V Procedures。
可回來查閱 RISC-V Symbolic Register Names。
a0
– a7
(x10
- x17
):8 個參數暫存器,用來傳遞參數及兩個 return value(a0
- a1
)。ra
:1 個 return address 暫存器,用來回到到原點(x1
)。s0
-s1
(x8
-x9
) 和 s2
-s11
(x18
-x27
): saved 暫存器(稍後會進一步解釋)。jal
)。
rd
暫存器中:
jal rd, FunctionLabel
jr
)。
ra
暫存器指定的位址:
jr ra
ret = jr ra
。小總結:
事實上,只有兩個指令:
jal rd, Label
– jump-and-link # rd = pc+4; pc += imm
jalr rd, rs, imm
– jump-and-link register # rd = pc+4; pc = R[rs1]+imm
jalr
時,我們跳躍到暫存器 rs
的內容加上立即值 imm
(就像基底指標加上偏移量),並且將 rd
設置為和 jal
相同的方式。注意:
j
,jr
和ret
是 pseudo-instructions!
在呼叫函數之前,需要一個地方來保存舊的值,返回時還原它們,並刪除這些值。
理想的選擇是 Stack:一種 LIFO 的佇列。
Stack 位於記憶體中,因此需要一個暫存器指向它。
RISC-V 中的 Stack Pointer 為 sp
(x2
)。
慣例上,Stack 從高位址向低位址增長,執行 Push 時減少 sp
,執行 Pop 時增加 sp
。
Stack frame 包含:
stack frame 是連續的記憶體區塊, Stack Pointer 會指示 stack frame 的底部位置。
當程式執行完畢後,stack frame 會從 Stack 中移除,釋放記憶體以供未來的 stack frame 使用。
int Leaf (int g, int h, int i, int j)
{
int f;
f = (g + h) – (i + j);
return f;
}
Parameter variables
g
,h
,i
, andj
in argument registersa0
,a1
,a2
, anda3
, andf
ins0
.
Assume need one temporary registers1
.
Leaf: addi sp,sp,-8 # adjust stack for 2 items
sw s1, 4(sp) # save s1 for use afterwards
sw s0, 0(sp) # save s0 for use afterwards
add s0,a0,a1 # f = g + h
add s1,a2,a3 # s1 = i + j
sub a0,s0,s1 # return value (g + h) – (i + j)
lw s0, 0(sp) # restore register s0 for caller
lw s1, 4(sp) # restore register s1 for caller
addi sp,sp,8 # adjust stack to delete 2 items
jr ra # jump back to calling routine
int sumSquare(int x, int y) {
return mult(x, x) + y;
}
有個名為 sumSquare
的函式,現在 sumSquare
呼叫了 mult
函式。
此時,sumSquare
需要 return 的 addr. 儲存在 ra
中,但在呼叫 mult
時,ra
會被覆寫。
因此,在呼叫 mult
之前,必須先將 sumSquare
的 return address 存放到 Stack 中,以避免被覆寫。
當 CalleE 執行完畢 return 時,CalleR 需要知道哪些暫存器可能會被改變,哪些則保證不會被改變。
暫存器慣例(Register Conventions):這是一組普遍接受的規則,說明在執行函式呼叫(jal
)後,哪些暫存器會保持不變,哪些可能會被改變。
為了減少因暫存器溢出與恢復所造成的昂貴 load 和 store 操作,RISC-V 的 function-calling convention 將暫存器分為兩類:
sp
(堆疊指標)、gp
(全域指標)、tp
(執行緒指標)。s0 - s11
(s0
也作為 fp
,即框架指標),a0 - a7
、ra
(返回位址暫存器)。t0 - t6
。Register:Numbers hardware understands。
ABI Name:Human-friendly symbolic names in assembly code.