You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:40:19