【问题标题】:C to MIPS troubleC 到 MIPS 的麻烦
【发布时间】:2012-03-25 21:24:59
【问题描述】:

所以我已经为此工作了几天,我已经成功地完成了所有这些工作,除了其中一部分让我感到难过。

int mystery(int a0)
{
    if (a0 == 0)
    {
        return 0;
    }
    else
    {
        return mystery(a0 - 1) + a0;
    }
}

我有这个递归函数,我有一些 MIPS 代码。 C 代码可以工作,但我的 MIPS 代码中的某个地方存在问题,导致它在输入 2 后无法正确输出。

.text

main:

li $a0, 2
jal mystery
move $a0, $v0
jal putDec
li $a0, '\n'
li $v0, 11
syscall

li $a0, 3
jal mystery
move $a0, $v0
jal putDec
li $a0, '\n'
li $v0, 11
syscall

li  $v0, 10     
syscall

putDec: 
    li $v0, 1
    syscall 
    jr  $ra     

mystery: 
 bne $0, $a0, recur 
 li $v0, 0      
 jr $ra             

  recur: 
sub $sp, $sp, 8     
sw $ra, 4($sp)  
sub $a0, $a0, 1
jal mystery         
sw $v0, 0($sp)  
jal mystery         
lw $t0, 0($sp)  
addu $v0, $v0, $t0  
addu $v0, $v0, 1    
add $a0, $a0, 1     
lw $ra, 4($sp)  
add $sp, $sp, 8     
jr $ra      

标签“神秘”的一切都很好,它只是作为一种形式来实际输入参数并在之后打印。我遇到的问题是获取高于 3 的值以打印出正确的数字。如果有人能看到我在哪里犯了错误,我们将不胜感激。谢谢

【问题讨论】:

  • 当你在调试器中运行它时发生了什么?
  • 在堆栈溢出上发布这个似乎是正确的。注意:阿克曼函数可能会更快。
  • 当我在 MARs 中运行它时,它会打印 3 和 7。
  • 如果有任何帮助,我将 putDec 中的 "li $v0, 11" 行更改为 "li $v0, 1" (是一个错误),同样当输入 3 作为参数时打印 6 我相信而不是 7。

标签: c assembly mips


【解决方案1】:

试着退后一步,比较一下 C 和汇编代码的结构,不要太在意细节。

在 C 代码中,有一个条件,导致要么是基本情况(它只返回一个值)要么是递归情况。递归案例执行减法、对mystery 的递归调用和加法。

现在看看汇编版本:这也有一个导致基本情况或递归情况的条件。但是看看递归案例的结构:那里有两个mystery的递归调用!这是一个强烈的暗示,它不太可能做同样的事情......

【讨论】:

  • +1 因为您似乎了解大多数 SO 头骨不了解的东西:回答这样的问题应该是教育的时刻,而不是获得简单答案的时刻。
【解决方案2】:

哇,经过大量的工作和一步一步地跟踪代码,我想我终于明白了,不得不做很多改变,但实际上现在看起来更容易了。这是代码,以防您想再次查看它,如果您发现我未测试的任何某些值可能会出现问题。感谢大家的帮助。

新的递归神秘函数:

mystery: 
 bne $0, $a0, recur     
 li $v0, 0      
 jr $ra             

 recur: 
  sub $sp, $sp, 8   
  sw $ra, 4($sp)    
  sw $a0, 0($sp)
  sub $a0, $a0, 1   
  jal mystery       
  lw $t0, 0($sp)    #
  addu $v0, $v0, $t0    
  lw $ra, 4($sp)    
  add $sp, $sp, 8   
  jr $ra        

再次感谢。 :)

【讨论】:

    【解决方案3】:

    您假设返回 ASCII 符号,将 putDec 中的 "li $v0, 1" 更改为 "li $v0, 11"(这不是错误)

    【讨论】:

    • 是的,最初这是我需要做的,但为了更好地理解基本概念,将其视为小数更容易。从那里我可以检查该数字将代表哪些 ascii 字符。这使得更容易找出问题并检查代码的正确性。然后,当我确定其他一切都正确时,我只需将系统调用值更改回 11。
    猜你喜欢
    • 2011-05-24
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    • 2017-02-23
    • 2013-12-01
    • 1970-01-01
    • 2018-09-14
    相关资源
    最近更新 更多