MIPS递归函数打印1到X时触发地址越界运行时异常求助
解决MIPS递归打印1到X时的栈地址越界异常
嘿,我来帮你梳理下这个递归函数的问题~你遇到的地址越界异常,本质是栈操作逻辑混乱加上递归逻辑错误导致的,咱们一步步来修复:
你的代码里的核心问题
- 未初始化的判断寄存器:你用
beq $t0, 0, EqZero来判断递归终止,但$t0从来没被赋值过!应该判断的是递归参数$a0是否为0才对。 - 递归逻辑完全颠倒:当前代码的分支逻辑搞反了——随机值的
$t0不为0时直接返回,反而进入分支才去递归,完全不符合“从1到X打印”的需求。 - 缺少打印操作:整个代码里没有调用打印数字的系统调用,根本不会输出任何内容。
- 栈操作不匹配:非终止分支里直接弹出栈空间返回,此时递归还没执行,栈的入栈出栈没有成对出现,会导致栈指针彻底混乱。
修正后的完整代码
.data .text # 初始化栈指针(关键:避免栈地址越界) li $sp, 0x7ffffff0 # 将栈顶设置到MIPS用户态合法高地址区域 # 获取用户输入 li $v0, 5 syscall move $a0, $v0 # 把输入的X存入$a0作为递归参数 jal PrintUp # 调用递归函数 # 程序退出 li $v0, 10 syscall # 递归函数:打印从1到$a0的数字 PrintUp: addi $sp, $sp, -8 # 分配8字节栈空间:保存返回地址和当前参数 sw $ra, 4($sp) # 保存返回地址到栈中 sw $a0, 0($sp) # 保存当前递归参数到栈中 beq $a0, 0, BaseCase # 终止条件:参数为0时跳转到基准情况 # 先递归处理X-1,完成从1到X-1的打印 addi $a0, $a0, -1 jal PrintUp # 递归返回后,打印当前的数字 lw $a0, 0($sp) # 恢复当前的参数值 li $v0, 1 syscall # 打印$a0中的数字 # 打印空格分隔(可选,让输出更清晰) li $a0, 32 li $v0, 11 syscall BaseCase: # 基准情况:参数为0时直接返回,不做额外操作 lw $ra, 4($sp) # 恢复返回地址 addi $sp, $sp, 8 # 释放栈空间 jr $ra # 返回调用者
关键修复点说明
- 栈指针初始化:开头添加
li $sp, 0x7ffffff0,把栈顶固定到合法区域,从根源避免地址越界。 - 正确的终止条件:用
beq $a0, 0, BaseCase判断参数是否为0,这才是递归的正确终止点。 - 递归逻辑调整:先递归处理
X-1,等递归返回后再打印当前的X,这样就能实现从1到X的顺序打印(递归会先深入到1,再从1依次打印到X)。 - 栈操作成对出现:每个分配栈空间的操作,在返回前都有对应的释放操作,保证栈指针始终处于正确位置。
- 添加打印逻辑:使用
li $v0, 1调用打印整数的系统调用,完成数字输出。
这样修改后,递归函数就能正常工作,也不会再触发栈地址越界的异常了。
内容的提问来源于stack exchange,提问作者Ahmed Naser
相关产品推荐
相关产品推荐

