1

I am trying to write a recursive function that prints numbers from 1 up to X, but I get this error, specifically at sw $a0, 0($sp).

.data

.text

# Getting user input
li $v0, 5
syscall
move $a0, $v0

PrintUp: 
     addi $sp, $sp, -8   #make a stack for two element 
     sw   $ra, 4($sp)    #save the address
     sw   $a0, 0($sp)    #save the argument 
     beq  $t0, 0, EqZero  #if X=0, go to EqZero
     addi $sp, $sp, 8  #pop the elements
     jr   $ra    #return
EqZero:
     addi $a0, $a0, -1    #decrement i
     jal  PrintUp  #call the recursive function
     lw   $a0, 0($sp)
     lw   $a0, 4($sp)
     addi $sp, $sp, 8  #pop the elements
     li $v0, 1       
     syscall 
     jr   $ra    #return
Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
  • Use your debugger to single step the code and see where it goes wrong. Also comment your code and describe what you want it to do. Hint: you never even change `$t0` so if it happens to be zero it stays zero and you get endless recursion. – Jester Mar 24 '18 at 19:49

1 Answers1

1

I've created two versions of your program. One with annotations for the bugs. And a cleaned up and working version. Please pardon the gratuitous style cleanup.

Here's the annotated version:

    .data

    .text

    # Getting user input
    li      $v0,5
    syscall
    move    $a0,$v0

# NOTE/BUG: doing fallthrough to PrintUp -- needs "jal PrintUp"

PrintUp:
    addi    $sp,$sp,-8              # make a stack for two element
    sw      $ra,4($sp)              # save the address
    sw      $a0,0($sp)              # save the argument

# NOTE/BUG: $t0 never set to anything -- should this be $a0?
    beq     $t0,0,EqZero            # if X=0, go to EqZero

# NOTE/BUG: does not restore $ra/$a0
    addi    $sp,$sp,8               # pop the elements
    jr      $ra                     # return

EqZero:
    addi    $a0,$a0,-1              # decrement i

    jal     PrintUp                 # call the recursive function

    lw      $a0,0($sp)

# NOTE/BUG: this should be $ra and not $a0
    lw      $a0,4($sp)
    addi    $sp,$sp,8               # pop the elements

# NOTE/BUG: this will only print the zero value
    li      $v0,1
    syscall

    jr      $ra                     # return

Here's the corrected version:

    .data
nl:         .asciiz     "\n"

    .text
    .globl  main
main:

    # Getting user input
    li      $v0,5
    syscall
    move    $a0,$v0

    jal     PrintUp

    # exit program
    li      $v0,10
    syscall

PrintUp:
    addi    $sp,$sp,-8              # make a stack for two element
    sw      $ra,4($sp)              # save the address
    sw      $a0,0($sp)              # save the argument

    bne     $a0,0,NeZero            # if X!=0, go to NeZero

    addi    $sp,$sp,8               # pop the elements
    jr      $ra                     # return

NeZero:
    addi    $a0,$a0,-1              # decrement i

    jal     PrintUp                 # call the recursive function

    lw      $a0,0($sp)
    lw      $ra,4($sp)
    addi    $sp,$sp,8               # pop the elements

    li      $v0,1
    syscall
    move    $t0,$a0

    li      $v0,4
    la      $a0,nl
    syscall

    move    $a0,$t0
    jr      $ra                     # return
Craig Estey
  • 30,627
  • 4
  • 24
  • 48