Assembly 递归斐波那契汇编MIPS码
我在模块编译器中为我的课程作业创建了一个代码生成器。它在MIPS汇编代码中生成代码,似乎工作正常(我测试过非常简单的程序和表达式)。 我测试了递归斐波那契程序,现在它永远循环。基本情况0和1正常工作。但当我尝试fib(2)或更多时,它会不断循环。 不知道是什么问题,有人能帮我找到吗 代码如下:Assembly 递归斐波那契汇编MIPS码,assembly,recursion,mips,fibonacci,Assembly,Recursion,Mips,Fibonacci,我在模块编译器中为我的课程作业创建了一个代码生成器。它在MIPS汇编代码中生成代码,似乎工作正常(我测试过非常简单的程序和表达式)。 我测试了递归斐波那契程序,现在它永远循环。基本情况0和1正常工作。但当我尝试fib(2)或更多时,它会不断循环。 不知道是什么问题,有人能帮我找到吗 代码如下: main: move $fp $sp sw $ra 0($sp) addiu $sp $sp -4 sw $fp 0($sp) addiu $sp $sp -4 li $a0 2 #testin
main:
move $fp $sp
sw $ra 0($sp)
addiu $sp $sp -4
sw $fp 0($sp)
addiu $sp $sp -4
li $a0 2 #testing comment
sw $a0 0($sp)
addiu $sp $sp -4
jal fib_entry
lw $ra 4($sp)
addiu $sp $sp 8
lw $fp 0($sp)
li $v0, 10
syscall
fib_entry:
move $fp $sp
sw $ra 0($sp)
addiu $sp $sp -4
lw $a0 4($fp)
sw $a0 0($sp)
addiu $sp $sp -4
li $a0 0
lw $t1 4($sp)
addiu $sp $sp 4
beq $a0 $t1 thenBranch1
elseBranch1:
lw $a0 4($fp)
sw $a0 0($sp)
addiu $sp $sp -4
li $a0 1
lw $t1 4($sp)
addiu $sp $sp 4
beq $a0 $t1 thenBranch2
elseBranch2:
sw $fp 0($sp)
addiu $sp $sp -4
lw $a0 4($fp)
sw $a0 0($sp)
addiu $sp $sp -4
li $a0 1
lw $t1 4($sp)
sub $a0 $t1 $a0
addiu $sp $sp 4
sw $a0 0($sp)
addiu $sp $sp -4
jal fib_entry
sw $a0 0($sp)
addiu $sp $sp -4
sw $fp 0($sp)
addiu $sp $sp -4
lw $a0 4($fp)
sw $a0 0($sp)
addiu $sp $sp -4
li $a0 2
lw $t1 4($sp)
sub $a0 $t1 $a0
addiu $sp $sp 4
sw $a0 0($sp)
addiu $sp $sp -4
jal fib_entry
lw $t1 4($sp)
add $a0 $a0 $t1
addiu $sp $sp 4
b endIf2
thenBranch2:
li $a0 1
endIf2:
b endIf1
thenBranch1:
li $a0 0
endIf1:
lw $ra 4($sp)
addiu $sp $sp 12
lw $fp 0($sp)
jr $ra
该代码存在各种问题
($sp)
)之前,应该先递减$sp
(尽管这只是按照惯例)$fp
(这是常识;)main
中是不平衡的main
返回,不要使用exit
syscallunsigned fib_entry(unsigned n) {
unsigned ret;
unsigned n1;
unsigned f1;
unsigned n2;
unsigned f2;
if (n <= 1) goto fib_small;
n1 = n - 1;
f1 = fib_entry(n1);
n2 = n - 2;
f2 = fib_entry(n2);
ret = f1 + f2;
goto fib_done;
fib_small:
ret = n;
fib_done:
return ret;
}
注:我故意让它未经优化。这种代码应该足够简单,可以生成。非常感谢您的回复,我将在您的帮助下修复我的代码^^
fib_entry:
addiu $sp $sp -28 # we need room for $ra, n, ret, n1, n2, f1, f2
sw $ra, 24($sp) # store $ra since not leaf function
sw $a0, 20($sp) # store n
lw $t0, 20($sp) # load n
ble $t0 1 fib_small
lw $t0, 20($sp) # load n
addi $t0 $t0 -1 # n - 1
sw $t0, 12($sp) # store as n1
lw $a0, 12($sp) # pass n1 as argument
jal fib_entry
sw $v0 4($sp) # store into f1
lw $t0, 20($sp) # load n
addi $t0 $t0 -2 # n - 2
sw $t0, 8($sp) # store as n2
lw $a0, 8($sp) # pass n2 as argument
jal fib_entry
sw $v0 ($sp) # store into f2
lw $t0 4($sp) # f1
lw $t1 ($sp) # f2
addu $t0 $t0 $t1 # f1 + f2
sw $t0 16($sp) # store into ret
b fib_done
fib_small:
lw $t0, 20($sp) # load n
sw $t0 16($sp) # store into ret
fib_done:
lw $v0 16($sp) # load return value
lw $ra 24($sp) # restore $ra
addiu $sp $sp 28 # restore stack
jr $ra # return