# This example shows an implementation of the mathematical
# factorial function (! function) to find the factorial value of !7 = 5040.
.data
argument: .word 7
str1: .string "Factorial value of "
str2: .string " is "
.text
main:
lw a0, argument # Load argument from static data
jal ra, fact # Jump-and-link to the 'fact' label
# Print the result to console
mv a1, a0
lw a0, argument
jal ra, printResult
# Exit program
li a7, 10
ecall
fact:
addi sp, sp, -16
sw ra, 8(sp)
sw a0, 0(sp)
addi t0, a0, -1
bge t0, zero, nfact
addi a0, zero, 1
addi sp, sp, 16
jr x1
nfact:
addi a0, a0, -1
jal ra, fact
addi t1, a0, 0
lw a0, 0(sp)
lw ra, 8(sp)
addi sp, sp, 16
mul a0, a0, t1
ret
# --- printResult ---
# a0: Value which factorial number was computed from
# a1: Factorial result
printResult:
mv t0, a0
mv t1, a1
la a0, str1
li a7, 4
ecall
mv a0, t0
li a7, 1
ecall
la a0, str2
li a7, 4
ecall
mv a0, t1
li a7, 1
ecall
ret
這段c code 是一個在 RISC-V 上實作數學 階乘函數(factorial function)的範例,目標是計算 7 的階乘(即 7! = 5040
),並將結果輸出到控制台。以下是分步解釋:
這個部分定義了靜態資料,包括要計算的參數和一些字串:
argument
: 定義要計算階乘的數字,這裡是 7
。str1
: 定義字串 "Factorial value of "。str2
: 定義字串 " is "。這裡是實際的程式碼,包括主程式 main
,階乘計算函數 fact
,以及結果輸出的 printResult
。
main
)lw a0, argument
: 從資料區段載入 argument
,即要計算的數字 7,並存入暫存器 a0
。jal ra, fact
: 跳到 fact
標籤,開始計算階乘,並將返回地址存入 ra
暫存器。mv a1, a0
: 把階乘計算結果從 a0
移動到 a1
,這是為了後續輸出。lw a0, argument
: 再次載入 argument
,為了在輸出時顯示原始數字。jal ra, printResult
: 跳到 printResult
函數進行結果輸出。li a7, 10
: 設定 a7
暫存器為 10,這是系統呼叫的代碼,用於退出程式。ecall
: 執行系統呼叫,退出程式。fact
)這裡是計算階乘的遞迴函數。
addi sp, sp, -16
: 將堆疊指標 sp
向下移動 16 字節,為儲存資料預留空間。sw ra, 8(sp)
: 將返回地址 ra
存入堆疊。sw a0, 0(sp)
: 將目前的參數 a0
(即階乘的值)存入堆疊。addi t0, a0, -1
: 將 a0
減去 1,存入暫存器 t0
,準備比較。bge t0, zero, nfact
: 如果 t0
大於或等於 0,跳到 nfact
,否則返回 1
(表示遞迴結束)。如果數字小於等於 1,則返回 1:
addi a0, zero, 1
: 將 a0
設為 1。addi sp, sp, 16
: 將堆疊指標 sp
恢復。jr x1
: 返回主程式。nfact
)處理當 a0 > 1
的情況:
addi a0, a0, -1
: 將 a0
減去 1。jal ra, fact
: 再次呼叫 fact
函數,進行遞迴。addi t1, a0, 0
: 將結果存入 t1
暫存器。lw a0, 0(sp)
: 從堆疊中取回原本的參數。lw ra, 8(sp)
: 從堆疊中取回返回地址。addi sp, sp, 16
: 將堆疊指標 sp
恢復。mul a0, a0, t1
: 計算階乘結果(a0 = a0 * t1
)。ret
: 返回主程式。printResult
函數負責將計算結果輸出到控制台:
a0
,然後通過 ecall
系統呼叫輸出:
將編寫RISC-V彙編程式(RV32I ISA)並透過環境呼叫輸出到控制台。