MIPS:为什么我的代码有时会搞乱?

时间:2014-04-08 02:36:05

标签: mips

确定,

所以我有一个主要的功能

jal gcd

我有这个代码。无论出于何种原因,它都没有正确缩进,但请耐心等待。

这是我的问题。出于某种原因,当只有一次调用gcd(来自main),并且gcd没有分支因为$ a1为0并且它跳转到exgcd,当$ ra,$ a1,$ a0被恢复时,它们都持有$ sp的地址,而不是之前应该存储的变量。

当gcd在第一次调用时没有转换为exgcd,即$ a1不为0时,递归结束时的加载工作正常并恢复正确的变量。

为什么它在第一种情况下不起作用?

谢谢。

我想补充一点,我知道甚至不需要存储$ ra,但我仍然很好奇它为什么不能正常工作。

为了让我的问题更清楚,为什么这段代码不起作用:

gcd:    addi    $sp, $sp, -12
    sw  $a0, 0($sp)
    sw  $a1, 4($sp)
    sw  $ra, 8($sp)
    addi    $sp, $sp, 12
    lw  $ra, 8($sp) # restore
    lw  $a1, 4($sp)
    lw  $a0, 0($sp)
    jr  $ra

完整功能:

gcd:    addi    $sp, $sp, -12
    sw  $a0, 0($sp)
    sw  $a1, 4($sp)
    sw  $ra, 8($sp)

    bne     $a1, $0, not0
    add $v0, $0, $a0
    j   exgcd   
not0:   sltu    $t0, $a1, $a0 # b<a?
    beq $t0, $0, bgta
    sub $t0, $a0, $a1
    add     $a0, $0, $a1
    add $a1, $a0, $0
    j   gcd 
bgta:   sub     $a1, $a1, $a0
    j   gcd
    j   exgcd
exgcd:  addi    $sp, $sp, 12
    lw  $ra, 8($sp) # restore
    lw  $a1, 4($sp)
    lw  $a0, 0($sp)
    jr  $ra

2 个答案:

答案 0 :(得分:1)

您修改了$ sp的地址,但尝试回读具有相同偏移量的值,您必须重新计算偏移量

exgcd:  addi    $sp, $sp, 12
    lw  $ra, -4($sp) # restore
    lw  $a1, -8($sp)
    lw  $a0, -12($sp)
    jr  $ra

答案 1 :(得分:1)

你分配一些堆栈空间并在那里存储函数参数,这很好。但是,在准备返回时,释放堆栈内存,然后尝试读取最初存储在堆栈中的内容。那是落后的。在 $sp指示后恢复lw 的原始值。

不要从已经弹出的堆栈位置读取。

您没有从您撰写的相同位置阅读。如果您正在阅读的位置恰好包含与其他位置中存储的值相似或相等的值,那么您的程序有时会显示以便工作,即使它真的被破坏了