budokiba
budokiba

Reputation: 31

C to MIPS trouble

So I have been working on this for a few days now, and I have managed to get through all of it except one part is getting me.

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

I have this recursive function and I have some MIPS code. The C code works but I have a problem somewhere in my MIPS code that is making it not come out correctly beyond putting in 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      

Everything up to the label 'mystery' is fine it is just there as a formality to actually put in arguments and print after. The problem I am having is getting values above 3 to print out the right numbers. Help would be greatly appreciated if someone could see where I am making my mistake. Thank you

Upvotes: 3

Views: 988

Answers (3)

xUCx
xUCx

Reputation: 1

you're suppose to return the ASCII symbol, change "li $v0, 1" in putDec to "li $v0, 11" (that was not a mistake)

Upvotes: 0

budokiba
budokiba

Reputation: 31

Whoo after extensive work and tracking the code one step at a time I think I finally got it, had to do quite a bit of changing but actually seems easier now. Here is the code in case you want to look over it again, if you can see a problem that could arise with any certain values I did not test. Thanks for the help all.

New recursive mystery function:

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        

Thanks again. :)

Upvotes: 0

Matthew Slattery
Matthew Slattery

Reputation: 46998

Try taking a step back, and comparing the structure of the C and assembly code, without worrying too much about the details.

In the C code, there is a conditional, leading to either a base case (which just returns a value) or the recursive case. The recursive case performs a subtraction, the recursive call to mystery, and an addition.

Now look at the assembly version: this, too, has a conditional leading to either a base case or a recursive case. But look at the structure of the recursive case: there are two recursive calls to mystery there! That's a strong hint that it's unlikely to be doing the same thing...

Upvotes: 2

Related Questions