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

为何用于计算数组偶数和的SPIM/MIPS程序无法正常运行?

解决MIPS数组偶数和计算的错误问题

嘿,作为MIPS新手能写出这样的代码已经很出色啦!咱们一步步拆解你遇到的问题,修复代码并理清结果差异~

首先分析报错原因

你遇到的Bad address和执行异常,核心问题是循环终止条件完全错误:

  • 你把$19设为固定值32,然后和存储数组地址的$16做比较。但$16是内存地址(比如初始是0x10000004,每次加4后会变成0x10000008、0x1000000C...),而$19是数值32,两者根本不是同一类型的变量,循环永远不会正常退出,最终导致程序访问了数组之外的非法内存地址,触发错误。

然后看结果错误的原因

你得到的-56其实是当前代码逻辑下的“意外正确”累加结果,但代码还有个关键漏洞:

  • $10寄存器在累加前没有初始化,它的初始值是随机的垃圾数据,这会导致累加结果不可预测(这次碰巧得到了逻辑上的偶数和,但换个运行环境结果可能完全不同)。

修正后的代码

.text
.globl main
main:
    lui $16, 0x1000       # 加载.data段基地址的高16位
    lw $17, 0($16)        # 读取数组大小size(值为8)
    addiu $18, $0, 2      # 除数2,用于判断偶数
    addiu $19, $0, 0      # 初始化计数器为0
    addiu $10, $0, 0      # 初始化累加寄存器$10为0!非常重要
    addiu $16, $16, 4     # $16指向数组array的起始地址

loop:
    beq $19, $17, exit    # 计数器等于数组大小时退出循环
    lw $20, 0($16)        # 读取当前数组元素到$20
    div $20, $18          # 元素除以2
    mfhi $13              # 获取余数到$13
    bne $13, $0, skip     # 余数不为0(奇数),跳过累加
    add $10, $10, $20     # 是偶数,累加到$10
skip:
    addiu $16, $16, 4     # 地址移动到下一个元素
    addiu $19, $19, 1     # 计数器加1
    j loop                # 回到循环开头

exit:
    sll $0, $0, 0         # 空指令,占位用

.data
size: .word 8
array: .word 23, -12, 45, -32, 52, -72, 8, 13

代码修正点说明

  1. 初始化累加寄存器:在开头添加addiu $10, $0, 0,确保$10从0开始累加,避免垃圾数据干扰结果。
  2. 正确的循环终止条件:用计数器$19和数组大小$17(值为8)比较,循环8次后退出,彻底避免访问非法内存。
  3. 优化分支逻辑:把奇数的处理改成bne ... skip,减少分支跳转的复杂度,让代码逻辑更清晰。
  4. 独立寄存器存数组元素:用$20存当前读取的数组元素,避免覆盖用来存储数组大小的$17。

关于结果的说明

按照你给出的数组,偶数元素是-12、-32、52、-72、8,它们的和是:
-12 + (-32) + 52 + (-72) + 8 = -56
所以修正后的代码运行后,$10的值会是-56,这是数学上的正确结果。你预期的25可能是计算时混淆了奇数/偶数,或者误将负数当成正数累加了~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:20:23