MIPS汇编$a/$v寄存器传参错误致计算结果异常求助
MIPS数组统计功能修正:解决平均值错误与寄存器传参问题
问题核心分析
你的代码存在两个致命问题:
- 平均值计算逻辑缺失:直接将总和(55)当作平均值输出,没有执行「总和÷数组长度」的除法操作,导致后续高于/低于平均值的统计完全失效。
- 寄存器使用混淆:错误地用
$v0存储计算数据,而$v0是MIPS系统调用的功能码专用寄存器(li $v0,1表示调用打印整数的系统调用),用它存数据会和系统调用逻辑冲突,覆盖计算结果。
修正方案与代码示例
1. 规范寄存器分配
优先使用s系列寄存器保存持久计算数据(总和、平均值、计数等),这类寄存器会被系统调用保留,不会被意外覆盖:
$s0:存储数组总和$s1:存储数组长度$s2:存储平均值(整数除法结果)$s3:高于平均值的元素数量$s4:低于平均值的元素数量$s5:等于平均值的元素数量$t系列寄存器用于临时遍历、取数等操作$v0仅用于指定系统调用功能码,$a0用于传递系统调用的参数(比如要打印的数值)
2. 修正平均值计算
在计算完总和后,必须执行除法操作得到平均值:
# 假设总和已存在$s0,数组长度已存在$s1 div $s0, $s1 # 总和 ÷ 长度,商存入$lo寄存器,余数存入$hi mflo $s2 # 将整数商(平均值)存入$s2
3. 正确打印平均值
打印时将平均值从s2移动到$a0,$v0仅存放系统调用功能码:
# 打印平均值 li $v0, 1 # 指定打印整数的系统调用 move $a0, $s2 # 将平均值传递给系统调用参数 syscall
4. 修正高于/低于平均值的统计逻辑
遍历数组时,明确分支判断,避免条件混淆:
# 初始化计数寄存器 li $s3, 0 # 高于平均值的数量 li $s4, 0 # 低于平均值的数量 li $s5, 0 # 等于平均值的数量 # 遍历数组(假设数组起始地址在$s6,当前索引$t0初始为0) count_loop: bge $t0, $s1, count_end # 索引超过长度时退出循环 lw $t1, ($s6) # 取出当前数组元素 bgt $t1, $s2, inc_higher # 元素>平均值,跳转到计数+1 blt $t1, $s2, inc_lower # 元素<平均值,跳转到计数+1 addi $s5, $s5, 1 # 元素=平均值,计数+1 j count_next inc_higher: addi $s3, $s3, 1 j count_next inc_lower: addi $s4, $s4, 1 count_next: addi $t0, $t0, 1 # 索引+1 addi $s6, $s6, 4 # 数组地址+4(每个整数占4字节) j count_loop count_end: # 后续打印$s3、$s4即可
验证结果(输入1-10时)
修正后输出应为:
- 总和:55
- 平均值:5(整数除法结果,若需浮点平均值需使用浮点寄存器)
- 最小值:1
- 最大值:10
- 高于平均值的数量:5(6-10)
- 低于平均值的数量:4(1-4)
内容的提问来源于stack exchange,提问作者Michaela Madison
相关产品推荐
相关产品推荐

