【问题标题】:MIPS: Why does the my code only sometimes mess up?MIPS:为什么我的代码只是有时会出错?
【发布时间】:2014-04-08 10:48:14
【问题描述】:

好的,

所以我有一个主要功能

jal gcd

我有这个代码。无论出于何种原因,它都没有正确缩进,但请多多包涵。

这是我的问题。出于某种原因,当只调用了一次 gcd(从主程序),并且 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

【问题讨论】:

    标签: mips


    【解决方案1】:

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

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

    您不是从您所写的相同位置阅读。如果您正在读取的位置恰好包含与存储在其他位置中的值相似或相等的值,那么您的程序可能似乎有时可以工作,即使它确实已损坏。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 但是为什么程序在分支时可以工作?
      • 没关系,它恰好可以工作,因为 a0 没有改变,而 a1 确实改变了
      猜你喜欢
      • 2020-10-18
      • 2021-12-31
      • 2022-12-06
      • 2021-07-10
      • 1970-01-01
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多