汇编语言成绩计算器优化:实现浮点平均值计算
汇编程序修改:整数平均值转浮点输出
我正在开发一款计算成绩列表平均值的汇编语言程序,找到的参考代码仅支持整数运算,无法满足需求。当前使用Craig Estey先生的代码,输入3个成绩90、90、91时,程序输出结果为90,需要修改程序使其输出90.33这样的浮点结果。
原程序代码
.data # NOTE/BUG: due to alignment issues put the .word directives _before_ # the [variable length] .asciiz directives size: .word 0 to_store: .word 0 sum: .word 0 avg: .word 0 size_prompt: .asciiz "Enter number of elements: " element_prompt: .asciiz "Enter an element: " msg_space: .asciiz " " .text .globl main main: # Prints prompt la $a0,size_prompt addi $v0,$0,4 syscall # Gets input from user addi $v0,$0,5 syscall sw $v0,size addi $t0,$0,0 # Initialise i = 0 # Creates the list lw $s0,size # get array count addi $t1,$0,4 # get 4 mult $s0,$t1 # get count * 4 mflo $t2 # get offset add $a0,$t1,$t2 addi $v0,$0,9 syscall stack: beq $t0,$s0,list_sum # done with number input? if yes, fly # prompt user for list element la $a0,element_prompt addi $v0,$0,4 syscall # read in element value addi $v0,$0,5 syscall sw $v0,to_store lw $t5,to_store # push element to stack addi $sp,$sp,-4 sw $t5,0($sp) addi $t0,$t0,1 # advance array index j stack # get sum of array elements list_sum: beq $s0,0,average # at end? if yes, fly lw $t6,sum # get previous sum lw $t7,0($sp) # get next array element value addi $sp,$sp,4 # advance array pointer add $t6,$t7,$t6 # sum += array[i] sw $t6,sum # store it addi $s0,$s0,-1 # bump down the _count_ j list_sum # NOTE/BUG: in the list_sum loop above, s0 is being decremented, so when we # get here it is _always_ zero average: lw $t0,sum # get the sum # print the sum li $v0,1 move $a0,$t0 syscall # NOTE/FIX: restore the count value lw $s0,size div $t0,$s0 # divide by count mflo $t0 sw $t0,avg # store average li $v0,4 la $a0,msg_space syscall # print average lw $a0,avg addi $v0,$0,1 syscall exit: li $v0,10 # exit program syscall
修改后的程序代码
.data # NOTE/BUG: due to alignment issues put the .word directives _before_ # the [variable length] .asciiz directives size: .word 0 to_store: .word 0 sum: .word 0 # 保留整数sum用于打印(可选) sum_float: .float 0.0 # 浮点类型总和 avg_float: .float 0.0 # 浮点类型平均值 size_prompt: .asciiz "Enter number of elements: " element_prompt: .asciiz "Enter an element: " msg_space: .asciiz " " newline: .asciiz "\n" # 新增换行优化输出排版 .text .globl main main: # Prints prompt la $a0,size_prompt addi $v0,$0,4 syscall # Gets input from user addi $v0,$0,5 syscall sw $v0,size addi $t0,$0,0 # Initialise i = 0 # Creates the list(原动态分配逻辑保留,未实际使用可按需移除) lw $s0,size # get array count addi $t1,$0,4 # get 4 mult $s0,$t1 # get count * 4 mflo $t2 # get offset add $a0,$t1,$t2 addi $v0,$0,9 syscall stack: beq $t0,$s0,list_sum # done with number input? if yes, jump # prompt user for list element la $a0,element_prompt addi $v0,$0,4 syscall # read in element value addi $v0,$0,5 syscall sw $v0,to_store lw $t5,to_store # push element to stack addi $sp,$sp,-4 sw $t5,0($sp) addi $t0,$t0,1 # advance array index j stack # get sum of array elements (浮点版本) list_sum: l.s $f0,sum_float # 初始化浮点总和为0.0 beq $s0,0,average # 无元素直接跳转到计算平均值 sum_loop: lw $t7,0($sp) # 读取栈中的整数元素 addi $sp,$sp,4 # 栈指针上移 # 将整数转换为单精度浮点数 mtc1 $t7,$f2 # 把整数加载到浮点协处理器寄存器 cvt.s.w $f2,$f2 # 整数转单精度浮点 add.s $f0,$f0,$f2 # 浮点累加:sum_float += 当前元素 addi $s0,$s0,-1 # 元素计数减1 bne $s0,0,sum_loop # 未处理完继续循环 s.s $f0,sum_float # 存储浮点总和 # 同步更新整数sum(可选,不需要可删除) cvt.w.s $f2,$f0 mfc1 $t6,$f2 sw $t6,sum average: # 打印整数sum(可选,不需要可注释) lw $t0,sum li $v0,1 move $a0,$t0 syscall li $v0,4 la $a0,msg_space syscall # 读取元素个数并转换为浮点 lw $t0,size mtc1 $t0,$f4 cvt.s.w $f4,$f4 # 浮点除法计算平均值:avg = sum_float / size_float l.s $f0,sum_float div.s $f2,$f0,$f4 s.s $f2,avg_float # 打印浮点平均值(系统调用2用于输出单精度浮点数) li $v0,2 mov.s $f12,$f2 syscall # 打印换行 li $v0,4 la $a0,newline syscall exit: li $v0,10 # exit program syscall
核心修改点说明
- 数据段调整:新增
sum_float和avg_float两个浮点变量,用于存储浮点类型的总和与平均值;保留原整数sum是为了兼容原有打印逻辑,不需要可直接删除。 - 求和逻辑重构:改用浮点寄存器
$f0存储累加和,每次读取整数元素后通过mtc1+cvt.s.w指令转换为浮点类型,再用add.s完成浮点累加。 - 平均值计算替换:将元素个数从整数转成浮点后,用
div.s指令执行浮点除法,替代原有的整数除法(会丢弃小数部分)。 - 输出逻辑更新:使用MIPS系统调用
2(li $v0,2)输出浮点数,结果需加载到$f12寄存器传递参数。 - 排版优化:新增换行符,让输出结果更清晰易读。
内容的提问来源于stack exchange,提问作者Kite
相关产品推荐
相关产品推荐

