大家好我正在尝试将我的斐波那契代码转换为MIPS汇编代码,但是,当我将MIPS代码运行到我的MIPS模拟器时,它似乎并没有结束。
C代码:
int fibo(int n)
{
if(n<2) return 1;
else f(n-1)+f(n-2);
}
int main()
{
fibo(5);
}
汇编代码:
main: addi $sp, $sp, -4
sw $ra, 0($sp)
addi $a0, $zero, 5
jal fibo;
lw $ra, 0($sp)
addi $sp, $sp, 4
fibo: addi $sp, $sp, -12
sw $s0, 0($sp)
sw $s1, 4($sp)
sw $ra, 8($sp)
slti $t0, $a0, 2
beq $t0, $zero, ELSE
addi $v0, $zero, 1
jr $ra
ELSE: addi $s0, $a0, 0
addi $a0, $a0, -1
jal fibo;
addi $s1, $v0, 0
addi $a0, $s0, -2
jal fibo
add $s1, $s1, $v0
j EXIT
EXIT: lw $s0, 0($sp)
lw $s1, 4($sp)
lw $ra, 8($sp)
addi $sp, $sp, 12
jr $ra
答案 0 :(得分:5)
这里有一些问题。
首先,您的main
函数缺少终止jr $ra
,这意味着main
在执行后落入fibo
。
其次,在if
语句中,您返回1
,直接调用jr $ra
,这意味着堆栈无法恢复。我通过拨打j EXIT
来解决这个问题。
最后,在其他人的末尾,您将f(n-1)
和f(n-2)
添加到$s1
。该寄存器应为$v0
,因为您打算返回此结果。
修正后的代码如下:
main:
addi $sp, $sp, -4
sw $ra, 0($sp)
addi $a0, $zero, 5
jal fibo
move $a0 $v0
li $v0 1
syscall
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
fibo:
addi $sp, $sp, -12
sw $s0, 0($sp)
sw $s1, 4($sp)
sw $ra, 8($sp)
slti $t0, $a0, 2
beq $t0, $zero, ELSE
addi $v0, $zero, 1
j EXIT
ELSE:
addi $s0, $a0, 0
addi $a0, $a0, -1
jal fibo
addi $s1, $v0, 0
addi $a0, $s0, -2
jal fibo
add $v0, $s1, $v0
EXIT:
lw $s0, 0($sp)
lw $s1, 4($sp)
lw $ra, 8($sp)
addi $sp, $sp, 12
jr $ra
答案 1 :(得分:1)
这是我的相同代码,但是它是用RISC-V编写的
.text
#x5 me n hai
#x7 me output
li x5 7
li x6 2
jal x1 FIB
j EXIT
FIB:
bge x5 x6 REC
addi x7 x5 0
jalr x0 0(x1)
#Handled Base Case
REC:
# Handling Rec. Case
addi sp sp -12
sw x1 0(sp)
sw x5 4(sp)
addi x5 x5 -1
jal x1 FIB
sw x7 8(sp)
lw x5 4(sp)
addi x5 x5 -2
jal x1 FIB
lw x13 8(sp)
add x7 x13 x7
lw x1 0(sp)
addi sp sp 12
jalr x0 0(x1)
EXIT:
答案 2 :(得分:0)
除了Konrad(https://stackoverflow.com/a/23185991/3729904)的答案之外,我注意到你的算法存在错误。如果n <2,则fib算法应该返回n而不是1。
这可以修改更改行:
addi $v0, $zero, 1
成:
add $v0, $zero, $a0