MIPS递归打印数组报错:无法扩展栈段,求技术解决方案
MIPS递归打印数组栈溢出问题修复
问题根源
你这段代码直接触发栈溢出的原因是递归终止条件完全错误:blt $a0, $a1, print_recursive 里,$a0 是数组的内存地址(比如0x10010000这类大数值),$a1 是元素个数10。地址数值远大于10,这个判断永远为真,导致程序无限递归调用print_recursive,每次调用都往栈里压入12字节的寄存器数据,直到栈空间被耗尽,就抛出了"Can't expand stack segment..."的错误。
另外还有两个隐性问题:
- 递归调用时,你只给
$a0加了1(应该加4,因为MIPS的.word占4字节) - 打印逻辑里,
lw $v0, 0($a0)读取数组元素后,立刻用li $v0, 1覆盖了寄存器值,导致根本没打印数组元素
修正后的代码
.data A: .word 21 16 -12 25 -25 12 -32 -56 19 -11 .text main: la $a0, A # argument 1: 数组起始地址 li $a1, 10 # argument 2: 剩余元素个数 jal print li $v0, 10 syscall print: addi $sp, $sp, -12 sw $ra, 0($sp) sw $a0, 4($sp) sw $a1, 8($sp) # 终止条件:剩余元素个数为0时返回 beq $a1, $zero, print_exit # 递归处理下一个元素:地址+4,剩余个数-1 addi $a0, $a0, 4 addi $a1, $a1, -1 jal print # 从栈恢复寄存器 lw $ra, 0($sp) lw $a0, 4($sp) lw $a1, 8($sp) # 打印当前元素 lw $a0, 0($a0) # 把数组元素加载到$a0(syscall 1需要的参数) li $v0, 1 syscall # 打印空格分隔(可选,让输出更清晰) li $a0, 32 li $v0, 11 syscall print_exit: addi $sp, $sp, 12 jr $ra
关键修正点
- 把递归终止条件改成
beq $a1, $zero, print_exit:当剩余元素个数为0时停止递归 - 递归调用前,
$a0 +=4(指向数组的下一个word),$a1 -=1(剩余元素减1) - 调整打印逻辑:用
$a0存要打印的数值,避免被li $v0,1覆盖读取到的元素值 - 增加了空格打印,让输出的数组元素更易读
内容的提问来源于stack exchange,提问作者Yoochan Lee
相关产品推荐
相关产品推荐

