我正在尝试用MIPS汇编语言实现斐波那契函数。我已经在下面编写了一些代码,并且它在没有任何错误的情况下通过运行时执行,我可以看到$ a0中的n值在每次迭代时都正确地下降。但是,$ v0中的结果永远不会设置,直到最后一次迭代,它返回2
代码:
data:
addi $a0, $zero, 10
fib:
slti $t0, $a0, 2 # check n <= 1
beq $t0, $zero, body # if previous statement was false, continue procedure
addi $v0, $zero, 1 # else return 1
jr $ra # return to body
body:
addi $sp, $sp, -16 # make room for 4 registers in stack
sw $a0, 0($sp) # save $a0 = n, to stack
sw $ra, 4($sp) # save return address to stack
addi $a0, $a0, -1 # $a0 = n - 1
jal fib # invoke fib(n-1) and save return address
sw $v0, 8($sp) # $v0 = fib(n-1), save to stack
addi $a0, $a0, -1 # $a0 = n - 2
jal fib # invoke fib(n-2) and save return address
sw $v0, 12($sp) # $v0 = fib(n-2), save to stack
lw $t0, 8($sp) # $t0 = fib(n-1)
lw $t1, 12($sp) # $t1 = fib(n-2)
addi $sp, $sp, 16 # pop from stack
add $v0, $t0, $t1 # $v0 = fib(n-1) + fib(n-2)
syscall # return
答案 0 :(得分:1)
根据您的ABI,堆栈指针应该指向堆栈上的第一个空地址,所以像
这样的行sw $a0, 0($sp) # save $a0 = n, to stack
如果程序在中断处理程序使用用户堆栈的系统中被中断,则应该避免使用。
您的代码遇到的更大问题是您的函数在使用n>1
调用时返回的方式:
syscall # return
完全错了。你不能syscall
返回!这是特别令人费解的,因为你使用
jr $ra # return to body
正确地在n<=1
案例中。
而不是syscall
,您需要使用
lw $ra, 4($sp) #restore link register
addi $sp, $sp, 16 #restore stack pointer
jr $ra #return