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

汇编语言成绩计算器优化:实现浮点平均值计算

汇编程序修改:整数平均值转浮点输出

我正在开发一款计算成绩列表平均值的汇编语言程序,找到的参考代码仅支持整数运算,无法满足需求。当前使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:50:26