如何解决使用RISC-VRV32I编译器无需递归即可计算第n个斐波那契数
我已经用RISC-V汇编语言编写了用于计算第n个斐波那契数的代码。它有两个部分-fib.s
和runtest.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,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,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,.FINISH
# Test 3
li a0,7
call fib
li a5,13
bne a0,.FINISH
# Test 4
li a0,9
call fib
li a5,34
bne a0,.FINISH
# Test 5
li a0,20
call fib
li a5,6765
bne a0,.FINISH
# Test 6
li a0,30
call fib
li a5,832040
bne a0,.FINISH
# Finished tests
li a5,0 # All passed
.FINISH:
mv a0,a5
li a7,93
ecall
每次运行此代码时,我只会得到一个返回值1。有人可以指出其中的错误吗?另外,如果有更好的方法来实现相同的逻辑,也请让我知道。
解决方法
我能够通过3个更改使您的所有测试台案例通过RISC-V模拟器:
(1)您的第二个测试用例具有错误的预期结果。我假设您使用的是0索引的斐波那契数字,因为这就是大多数测试用例所做的事情(例如,测试用例1表示斐波那契数字1是1,测试用例3表示斐波那契数字7是13)。在这种情况下,斐波那契数3应该是2,而不是3。
(2)为了获得正确的迭代次数,在循环中,您的“ i”变量/寄存器a4应该开始设置为1,而不是2。
(3)通常,您不使用ECALL从RISC-V中的函数返回。根据RISC-V规范,“ ECALL指令用于向执行环境发出服务请求。”它会导致一个精确的陷阱,并在实施syscall时使用(例如)。而是有一个伪指令ret从函数调用中返回(与x86相似的符号)。 ret等于jalr x0 0(ra)。 (也就是说,也许您已定义了ecall行为,使得当a7为93时,将执行等效于ret的操作。)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。