I'm trying to implement a double recursion program using MIPS that follows this pseudocode:
procedure DRAGON(order, sign)
if order = 0 then
Move forward
else
DRAGON(order-1; 1)
Turn 90sign
DRAGON(order-1; -1)
This is what I have until now, but when I run it, I get this error:
Can't expand stack segment by 16 bytes to 524288 bytes.
Use -lstack # with # > 524288
I'm new to MIPS so it's really difficult for me to debug this. I suspect that it's probably because I'm making infinite recursive calls, but I'm not sure how to fix this. Could anyone be able to help point out what the problem is?
.data
# SVG path segment commands
up: .asciiz "v-5"
right: .asciiz "h5"
down: .asciiz "v5"
left: .asciiz "h-5"
# Print one of the path segment strings by readings its address
# from this array of pointers
.align 2
dirs: .word up, right, down, left
# Keep the current direction (0-3) in this single byte value
direction:
.byte 3
.text
# $a0 = order (an unsigned integer)
# $a1 = sign (either 1 or -1)
.globl dragon
dragon:
addiu $sp, $sp, -16 # allocate space on stack (multiple of 8)
la $t0, dirs # t0: dirs array address
lbu $t1, direction # t1: load current direction byte
move $t6, $t1 # t6: copy of current direction byte
li $t2, 1 # t2: load constant 1
li $t3, -1 # t3: load constant -1
sw $ra, 0($sp)
sw $a0, 4($sp)
sw $a1, 8($sp)
beq $a0, $0, base
move $t4, $a1 # t4: keep current sign (1 or -1)
addiu $a0, $a0, -1 # order = order - 1
move $a1, $t2 # sign = 1
jal dragon # dragon(order-1, 1)
li $v0, print_int
move $a0, $a1
syscall
addu $t5, $t6, $t4
addiu $t5, $t5, 4
div $t5, $t5, 4
mfhi $t6 # t1: (direction + sign + 4) % 4 -> new direction
sb $t6, direction
move $a1, $t3
jal dragon # dragon(order-1, -1)
j done
base: # when order = 0
addu $t1, $t1, $t1
addu $t1, $t1, $t1 # direction * 4
addu $t5, $t1, $t0 # base address + offset
lw $t5, 0($t5) # t5: direction from array dirs
li $v0, print_string
move $a0, $t5
syscall # print direction
done:
lw $ra, 0($sp)
lw $a0, 4($sp)
lw $a1, 8($sp)
addiu $sp, $sp, 16
jr $ra
#
# Main program
#
.data
svg_header:
.asciiz "<svg xmlns=\"http://www.w3.org/2000/svg\">\n"
svg_footer:
.asciiz "</svg>\n"
path_header:
.asciiz "<path stroke=\"black\" fill=\"none\" d=\"M225 225"
path_footer:
.asciiz "\" />\n"
.text
.globl main
main:
move $s0, $ra
la $a0, svg_header
li $v0, print_string
syscall
la $a0, path_header
syscall
li $a0, 3 # Order
li $a1, 1 # Sign
jal dragon
la $a0, path_footer
li $v0, print_string
syscall
la $a0, svg_footer
syscall
li $v0, 10
syscall
In your recursive fragment, you don't return before the base
bits. So after the second jal dragon
, your code falls through to the base scenario, which is wrong by any account. By that time, t1
no longer contains the direction
variable - it's been multiplied by four. In the base
, the code tries to resolve t1
as if it still was the direction
and faults.