Reputation: 11
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
Upvotes: 1
Views: 1188
Reputation: 33601
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
Upvotes: 1