程序集fibonacci返回正确的结果,但在最后一次迭代时崩溃

时间:2014-09-28 08:15:56

标签: assembly mips

我已经为斐波那契函数编写了以下汇编代码。它的工作原理是在终止时将正确的结果放在$ v0中,但程序也会因异常Error in : invalid program counter value: 0x00000000

而崩溃

这是我的代码:

main:
    li $a0, 5
    j fib

fib: 
    bgt $a0, 1, body     # continue if $a0 is larger than 1
    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

    lw $a0, 0($sp)     # reset argument to original
    addi $a0, $a0, -2  # $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)
    lw $ra, 4($sp)
    addi $sp, $sp, 16  # pop from stack

    add $v0, $t0, $t1  # $v0 = fib(n-1) + fib(n-2)

    jr $ra             # jump to return address

关于我的程序如何工作而不崩溃的任何建议?非常感谢

1 个答案:

答案 0 :(得分:2)

让我们通过您的程序执行fib(1),看看它失败的原因:

main:
    li $a0, 1            # edited for brevity...
    j fib                # make a note here.

fib: 
    bgt $a0, 1, body     # won't branch...
    addi $v0, $zero, 1   # else return 1
    jr $ra               # return to caller?

此崩溃,因为您在j fib中使用了main()$ra的内容是main()的内容,幸运的是它们是一个无效值,因此您崩溃而不是在某处执行奇怪的代码。

但它变得更糟。即使用正确的j fib替换jal fib,在返回后仍然会出现问题,因为main()没有终止(系统调用或返回)或循环,但是而是继续进入fib()。这会受伤。