基于MARS模拟器的MIPS汇编实现计数排序与数据均值求解
在MARS模拟器中用MIPS实现计数排序并求解数组平均值
实现方法说明
计数排序完整流程
- 遍历数组找到最大值,以此确定计数数组的长度(最大值+1)
- 初始化计数数组,所有元素设为0
- 再次遍历原数组,统计每个元素出现的次数,更新计数数组
- 根据计数数组的统计结果,将元素按顺序写回原数组,完成排序
平均值计算流程
- 遍历数组累加所有元素的总和
- 用总和除以数组元素个数(这里采用整数除法,若需浮点结果可扩展指令)
- 输出总和与平均值,便于在MARS模拟器中验证结果
补充后可运行的完整MIPS代码
.data array: .word 2, 10, 6, 8, 4, 5, 1, 4, 10, 9 n: .word 10 max: .word 0 count: .space 44 # 预留(max + 1)*4字节空间 sum_msg: .asciiz "数组总和:" avg_msg: .asciiz "\n数组平均值:" .text .globl main main: # 步骤1:查找数组中的最大元素 lw $t0, array($zero) sw $t0, max($zero) li $t1, 1 # 遍历索引i初始化为1 lw $t2, n($zero) loop1: bge $t1, $t2, init_count # i >= n时退出循环 sll $t3, $t1, 2 # 计算数组偏移量:i*4 lw $t4, array($t3) # 获取array[i] lw $t5, max($zero) ble $t4, $t5, continue_loop1 sw $t4, max($zero) # 更新最大值 continue_loop1: addiu $t1, $t1, 1 j loop1 # 步骤2:初始化计数数组为0 init_count: li $t1, 0 # 计数数组索引i初始化为0 li $t4, 0 lw $t2, max($zero) addiu $t2, $t2, 1 # 计数数组长度为max+1 count_loop_init: beq $t1, $t2, count_elements # 遍历完计数数组后退出 sll $t3, $t1, 2 # 计算计数数组偏移量:i*4 sw $t4, count($t3) addiu $t1, $t1, 1 j count_loop_init # 步骤3:统计每个元素出现的次数(原代码缺失的核心步骤) count_elements: li $t1, 0 # 原数组索引i初始化为0 lw $t2, n($zero) count_loop: bge $t1, $t2, sort_array # i >= n时退出 sll $t3, $t1, 2 lw $t4, array($t3) # 获取array[i] sll $t5, $t4, 2 # 计算计数数组对应偏移量:元素值*4 lw $t6, count($t5) addiu $t6, $t6, 1 # 计数+1 sw $t6, count($t5) addiu $t1, $t1, 1 j count_loop # 步骤4:根据计数数组完成排序 sort_array: li $t1, 0 # 计数数组索引i初始化为0 li $t4, 0 # 原数组写入索引j初始化为0 lw $t2, max($zero) addiu $t2, $t2, 1 sort_loop: beq $t1, $t2, calculate_sum # 遍历完计数数组后退出 sll $t3, $t1, 2 lw $t5, count($t3) # 获取当前元素的计数 beqz $t5, continue_sort # 计数为0则跳过当前元素 sw $t1, array($t4) # 将元素写入原数组 addiu $t4, $t4, 4 # 原数组写入索引+4 addiu $t5, $t5, -1 # 计数-1 sw $t5, count($t3) # 更新计数数组 j sort_loop # 继续写入当前元素直到计数为0 continue_sort: addiu $t1, $t1, 1 j sort_loop # 步骤5:计算数组总和与平均值 calculate_sum: li $t1, 0 # 遍历索引i初始化为0 li $t6, 0 # 总和sum初始化为0 lw $t2, n($zero) sum_loop: bge $t1, $t2, calculate_avg sll $t3, $t1, 2 lw $t4, array($t3) add $t6, $t6, $t4 # sum += array[i] addiu $t1, $t1, 1 j sum_loop calculate_avg: lw $t2, n($zero) div $t6, $t2 # 执行sum / n,结果存入lo寄存器 mflo $t7 # 取出整数平均值 # 输出总和 li $v0, 4 la $a0, sum_msg syscall li $v0, 1 move $a0, $t6 syscall # 输出平均值 li $v0, 4 la $a0, avg_msg syscall li $v0, 1 move $a0, $t7 syscall # 程序结束 exit: li $v0, 10 syscall
关键修正与说明
- 补全计数排序核心逻辑:新增
count_elements循环统计元素出现次数,这是原代码缺失的关键步骤,没有这一步计数数组无法指导排序。 - 修正排序逻辑:原
sort_loop逻辑错误,改为遍历计数数组的索引(即元素值),根据计数次数将元素依次写回原数组,保证排序正确性。 - 实现平均值计算:
- 通过
calculate_sum循环累加数组所有元素得到总和 - 使用MIPS的
div指令完成整数除法,mflo取出商作为平均值 - 增加提示字符串与系统调用,直接在MARS模拟器控制台输出结果
- 通过
内容的提问来源于stack exchange,提问作者Amirhosein Moayed
相关产品推荐
相关产品推荐

