MIPS程序求和异常求助:输入≥32时计算结果错误
问题诊断与修复建议
核心问题:8位有符号整数溢出
你的程序异常是因为数组元素误用8位有符号字节存储,而非32位整数类型:
- 当x≥32时,x*4=128,这超出了8位有符号整数的最大值(127),会被补码截断为-128;
- 你看到的“存入数组时数据正确”,大概率是调试时按无符号值解析,但实际存储的是溢出后的有符号字节,读取累加时按有符号数处理就会出现负数。
具体修复步骤
- 修改存储/读取指令:将数组操作的字节指令(
sb/lb/lbu)替换为32位字指令(sw/lw):- 错误写法:
sb $t0, 0($s0)(存字节)、lb $t0, 0($s0)(读字节) - 正确写法:
sw $t0, 0($s0)(存32位字)、lw $t0, 0($s0)(读32位字)
- 错误写法:
- 调整地址偏移量:由于32位字占4字节,循环中数组地址的增量要从
addi $s0, $s0, 1改为addi $s0, $s0, 4。 - 验证累加寄存器:确保累加使用32位通用寄存器(如
$s1),n=100时的总和为20200,远小于32位有符号整数的最大值(2147483647),不会出现累加溢出。
代码修正示例
假设原存储循环代码如下:
loop_store: mul $t0, $t1, 4 # 计算x*4 sb $t0, 0($s0) # 错误:存入字节数组 addi $s0, $s0, 1 # 错误:地址增量为1 addi $t1, $t1, 1 bne $t1, $a0, loop_store
修正后:
loop_store: mul $t0, $t1, 4 # 计算x*4 sw $t0, 0($s0) # 正确:存入32位字数组 addi $s0, $s0, 4 # 正确:地址增量为4 addi $t1, $t1, 1 bne $t1, $a0, loop_store
读取累加的循环部分做同样修改即可,修正后输入32时会得到正确结果2112,输入100时得到正确结果20200。
内容的提问来源于stack exchange,提问作者Daniel Nelson
相关产品推荐
相关产品推荐

