簡體   English   中英

使用 RISC-V (RV32I) 編譯器無需遞歸計算第 n 個斐波那契數

[英]Calculate nth Fibonacci number using RISC-V (RV32I) compiler without recursion

我寫了一個代碼,用於用 RISC-V 匯編語言計算第 n 個斐波那契數。 它有兩部分 - fib.sruntest.s ,它將n的值加載到a0並調用fib ,它計算第 n 個斐波那契數(沒有遞歸),將結果加載到a0本身並返回。 這是我的代碼:

.global fib              # the runtest.s will give an a0 value as input n and call fib 
fib:
    li a1, 0             # This is a
    li a2, 1             # This is b
    li a3, 0             # This is c 
    li a4, 2             # This is i
   
    li a6, 2             # dummy, just to check a0 with
    ble a0, a6, cond1    # check if a0 <= 2
    bgt a0, a6, head     # if a0 > 2, proceed to loop

head:                    # start of loop
    add a3, a1, a2       # Here I'm implementing the space optimized version of fibonacci series without recursion:
    mv a1, a2            # for i in range(2, n+1): c = a + b; a = b; b = c; return b
    mv a2, a3            
    addi a4, a4, 1
    blt a4, a0, head
    bge a4, a0, end      # iterates n-1 times and goes to end

cond1:
    li a0, 1             # if n==1 or n==2 return 1
    li a7, 93
    ecall

end:
    mv a0, a2            # copying the value of a2 (which is b) to a0, since the testbench
    li a7, 93            # runtest.s is setup that way.
    ecall

這是我的測試平台( runtest.s ):

.global _start
_start:
    # Load 'n' into a0 and call fib
    # Test 1
    li      a0,1  # Check n'th Fib number
    call    fib
    li      a5,1  # Expected result
    bne     a0,a5,.FINISH
    # Test 2
    li      a0,3  
    call    fib
    li      a5,3  
    bne     a0,a5,.FINISH
    # Test 3
    li      a0,7  
    call    fib
    li      a5,13  
    bne     a0,a5,.FINISH
    # Test 4
    li      a0,9 
    call    fib
    li      a5,34
    bne     a0,a5,.FINISH
    # Test 5
    li      a0,20 
    call    fib
    li      a5,6765 
    bne     a0,a5,.FINISH
    # Test 6
    li      a0,30
    call    fib
    li      a5,832040 
    bne     a0,a5,.FINISH
    # Finished tests
    li      a5,0  # All passed
.FINISH:
    mv      a0, a5
    li      a7, 93
    ecall

每次我運行這段代碼時,我只得到一個返回值 1。有人能指出這里的錯誤嗎? 另外,如果有更好的方法來實現相同的邏輯,也請告訴我。

我能夠通過 RISC-V 模擬器通過 3 處更改讓您的所有測試平台案例通過:

(1) 你的第二個測試用例有錯誤的預期結果。 我假設您使用的是 0 索引的斐波那契數,因為這是您的大多數測試用例所做的(例如,測試用例 1 表示斐波那契數 1 為 1,測試用例 3 表示斐波那契數 7 為 13)。 在這種情況下,斐波那契數 3 應該是 2,而不是 3。

(2) 要獲得正確的迭代次數,在您的循環中,您的“i”變量/寄存器 a4 應開始設置為 1,而不是 2。

(3) 你通常不使用 ECALL 從 RISC-V 中的函數返回。 根據 RISC-V 規范,“ECALL 指令用於向執行環境發出服務請求。” 它會導致一個精確的陷阱,並在實現系統調用時使用(例如)。 相反,有偽指令 ret 從函數調用返回(與 x86 類似的符號)。 ret 等價於 jalr x0 0(ra)。 (話雖如此,也許您已經定義了 ecall 行為,以便當 a7 為 93 時,將執行 ret 的等效項。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM