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

MIPS代码出现地址越界、溢出错误及死循环问题求助

问题分析与修复

1. 地址越界 + 死循环问题

根源:

  • 循环终止条件错误:la $t9, ArraySize是把ArraySize的内存地址加载到$t9,而非它存储的数值19。$t2是计数器(0~19),永远不可能等于一个内存地址,导致循环永远无法触发beq $t2, $t9, LoopEnd终止,持续递增数组指针$t0、$t1,最终超出数组范围引发地址越界。
  • 数组遍历逻辑:假设A、B是包含20个(x,y)结构体的数组(每个结构体占8字节),正常遍历应执行20次循环(索引0~19),但错误的终止条件导致无限遍历。

修复:

如果ArraySize在.data段定义为.word 19,将la $t9, ArraySize改为lw $t9, ArraySize;或者直接用li $t9, 19加载终止值,避免依赖内存中的常量。


2. 溢出错误 + 逻辑混乱问题

根源:

  • 核心逻辑错误:你原本想用$t8存储当前最小距离,但当发现更小距离时,错误执行了add $t8, $t2, $zero,把索引值覆盖到了$t8中。后续bgt $t7, $t8变成比较当前距离和索引(索引最大19),而距离最小值为0、最大值可达(500 - (-500))² + (500 - (-500))² = 2,000,000,必然满足$t7 > $t8,导致所有迭代都跳转到pass分支,同时$t8被持续覆盖为索引,完全偏离了“存储最小距离”的设计。
  • 溢出误解:理论上,两个平方值相加的最大值为2,000,000,远小于32位有符号整数的上限(2,147,483,647),用add本不应溢出。你遇到的溢出是因为循环无限执行,加载了数组外的非法数据(地址越界后读取的垃圾值),这些值平方后可能超出有符号整数范围,触发add的溢出检查。

修复:

  • 新增一个寄存器存储最小距离对应的索引,比如$s0:
    • 初始化时li $s0, 0(默认索引0为最小)
    • 当发现当前距离$t7小于$t8时,更新$t8 = $t7(存储新的最小距离),同时$s0 = $t2(记录对应索引)
  • 修正比较后的赋值逻辑:
    bgt $t7, $t8, pass # 当前距离更大,跳过更新
    move $t8, $t7      # 更新最小距离
    move $s0, $t2      # 记录当前索引
    

3. 其他细节问题

  • 拼写错误:addi $t1, $t1, 8 # increase potision of array by 8 bytes中的potision应为position,不影响执行但建议修正。
  • 初始值合理性:li $t8, 10000作为初始最小距离,虽然小于最大可能的2,000,000,但可以直接设为最大可能值(比如li $t8, 2000000),避免极端情况漏判。

修复后的完整代码示例(关键部分修正)

.data
A:         .word 1, 2, 3, 4, ...  # 填充你的20个(x,y)结构体数据
B:         .word 5, 6, 7, 8, ...
ArraySize: .word 19               # 终止索引19

.text
la $t0, A
la $t1, B
li $t2, 0                         # 计数器i
lw $t9, ArraySize                 # 加载终止值19
li $t8, 2000000                   # 初始最小距离设为最大可能值
li $s0, 0                         # 初始最小索引为0

loop:
beq $t2, $t9, LoopEnd             # 循环终止条件
lw $t3, 0($t0)                    # A[i].x
lw $t4, 0($t1)                    # B[i].x
lw $t5, 4($t0)                    # A[i].y
lw $t6, 4($t1)                    # B[i].y

# 计算距离平方
sub $t4, $t3, $t4
mul $t4, $t4, $t4

sub $t6, $t5, $t6
mul $t6, $t6, $t6

addu $t7, $t6, $t4                # 相加用addu或add均可,这里不会溢出

# 更新最小距离和索引
bgt $t7, $t8, pass
move $t8, $t7
move $s0, $t2

pass: 
addi $t2, $t2, 1
addi $t0, $t0, 8
addi $t1, $t1, 8
j loop

LoopEnd:
# 此处添加打印逻辑,输出$s0(最小距离对应的索引)
# 比如用syscall打印整数
li $v0, 1
move $a0, $s0
syscall

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 12:26:19