MIPS程序集中的Fibonacci没有返回正确的答案

时间:2014-09-13 14:52:59

标签: assembly mips

我正在尝试用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

1 个答案:

答案 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
相关问题