MIPS 双重递归问题“无法将堆栈段扩展 16 字节至 524288 字节”
MIPS Double Recursion Problem " Can't expand stack segment by 16 bytes to 524288 bytes"
我正在尝试使用遵循以下伪代码的 MIPS 实现双重递归程序:
procedure DRAGON(order, sign)
if order = 0 then
Move forward
else
DRAGON(order-1; 1)
Turn 90sign
DRAGON(order-1; -1)
这是我到目前为止所拥有的,但是当我 运行 它时,我得到了这个错误:
Can't expand stack segment by 16 bytes to 524288 bytes.
Use -lstack # with # > 524288
我是 MIPS 的新手,所以我很难调试它。我怀疑这可能是因为我正在进行无限递归调用,但我不确定如何解决这个问题。谁能帮忙指出问题所在?
.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, [=12=], 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
在您的递归片段中,您没有 return 在 base
位之前。因此,在第二个 jal dragon
之后,您的代码会落入基本场景,这对任何帐户来说都是错误的。到那时,t1
不再包含 direction
变量 - 它已乘以四。在 base
中,代码尝试解析 t1
,就好像它仍然是 direction
和错误一样。
我正在尝试使用遵循以下伪代码的 MIPS 实现双重递归程序:
procedure DRAGON(order, sign)
if order = 0 then
Move forward
else
DRAGON(order-1; 1)
Turn 90sign
DRAGON(order-1; -1)
这是我到目前为止所拥有的,但是当我 运行 它时,我得到了这个错误:
Can't expand stack segment by 16 bytes to 524288 bytes.
Use -lstack # with # > 524288
我是 MIPS 的新手,所以我很难调试它。我怀疑这可能是因为我正在进行无限递归调用,但我不确定如何解决这个问题。谁能帮忙指出问题所在?
.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, [=12=], 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
在您的递归片段中,您没有 return 在 base
位之前。因此,在第二个 jal dragon
之后,您的代码会落入基本场景,这对任何帐户来说都是错误的。到那时,t1
不再包含 direction
变量 - 它已乘以四。在 base
中,代码尝试解析 t1
,就好像它仍然是 direction
和错误一样。