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

MIPS汇编栈段扩展失败报错处理及归并排序代码解析

MIPS归并排序栈溢出问题排查与代码解析

一、栈溢出报错的核心原因

你遇到的“无法将栈段扩展16字节至524288字节”报错,本质是栈内存越界写入导致的栈结构破坏,具体问题出在merge函数的栈操作上:

merge:
# params: list, l=$t2, m=$t4, r=$t5
add $sp, $sp, -12  # 仅分配12字节栈空间
sw $ra, 0($sp)
sw $s1, 4($sp)
sw $t2, 8($sp)
sw $t1, 12($sp)  # 越界!12字节栈的有效索引范围是0-11

你只给栈分配了12字节,但最后一条sw指令试图写入栈的第13个字节(从0开始计数),每次调用merge都会破坏栈外的内存区域,反复操作后最终触发栈溢出报错。

快速修复方案

  1. 把栈分配大小改成16字节:将add $sp, $sp, -12改为add $sp, $sp, -16,足够容纳4个寄存器的存储需求
  2. 修正寄存器恢复顺序(当前出栈顺序和入栈顺序不匹配):
# 错误的恢复顺序
lw $ra, 0($sp)
lw $s1, 8($sp)
lw $t2, 4($sp)
lw $t1, 12($sp)

# 改成正确的对应顺序
lw $ra, 0($sp)
lw $s1, 4($sp)
lw $t2, 8($sp)
lw $t1, 12($sp)

二、代码逻辑全解析

1. 主函数(main)流程

  • 提示用户输入数组长度n,循环读取n个元素存入list数组
  • 计算数组总字节数(arraySize)和数组末尾地址(arrayEndAddress)
  • 调用mergeSort执行排序,完成后调用printArray输出结果,最后终止程序

2. 迭代式归并排序(mergeSort)

这是迭代版的归并排序(非递归实现),核心逻辑:

  • 用curr_size($t1)表示当前待合并的子数组长度,初始为1,每次循环翻倍
  • 外层for1循环控制子数组长度,直到curr_size超过数组最大索引(n-1)
  • 内层for2循环遍历数组,每次选取两个相邻子数组:左子数组范围[left_start, mid],右子数组范围[mid+1, right_end]
  • 调用merge合并两个子数组,然后移动到下一组待合并的子数组

3. 合并函数(merge)

负责将两个有序子数组合并回原数组,逻辑框架:

  • 把左子数组(l到m)复制到临时数组Left,右子数组(m+1到r)复制到临时数组Right
  • 用双指针法遍历Left和Right,将较小的元素依次写回原数组list
  • 最后将Left或Right中剩余的元素全部写回原数组

⚠️ 注意:merge里的RightInput段还有逻辑错误,当前的$t7计算会导致Right数组写入位置混乱,应该改成:

# 错误的写法
add $t7,$t7, $s1
sll $t7, $t7, 2

# 改成正确的索引计算
sll $t7, $s1, 2  # 用s1作为索引,乘以4得到字节偏移

内容的提问来源于stack exchange,提问作者Waldo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 06:49:06