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

如何用MIPS Assembly从数组提取整数并实现求和打印?

MIPS汇编:输入整数数组求和问题修正

问题说明

使用MARS IDE编写MIPS汇编代码,目标是从用户输入的字符串中提取整数存入堆数组,然后求和并打印。目前能正确存储输入值到堆中,但无法正确提取值计算总和,附上测试打印语句。

原代码中的关键错误

  • 数组基地址丢失:在endGetNIntsLoop中执行la $t2, 0会将$t2设置为0地址,彻底丢失了之前用syscall 9分配的数组基地址,后续无法正确读取数组元素。
  • 测试打印逻辑错误:尝试打印数组第一个元素时用la $t3, 0($t2)是取地址而非数值,应该用lw指令加载内存中的值。
  • 求和循环的潜在混淆:求和时通过subi $t2, $t2, 4往回遍历数组,虽然求和结果不受顺序影响,但搭配错误的$t2值会完全读取错误的内存区域。

修正后的代码

.data
    prompt1: .asciiz "Enter an int n (# of integers): "
    prompt2: .asciiz "Input "
    prompt3: .asciiz " \nwith a space between each value, then press enter: "
    newLine: .asciiz "  \n"
    
    inputString: .space 100  # 修正:用.space而非.word分配字符串空间

.text

main:
    # 提示输入n
    li $v0, 4
    la $a0, prompt1
    syscall

    # 获取用户输入的n
    li $v0, 5
    syscall
    move $t0, $v0  # n存到$t0

    # 计算数组所需字节数并分配堆内存
    li $t4, 4           
    mul $a0, $t0, $t4   
    mflo $t1            
    li $v0, 9
    move $a0, $t1
    syscall
    move $t2, $v0       # $t2用于遍历数组存数
    move $t7, $v0       # 保存数组基地址到$t7,后续求和用
        
    # 提示输入n个整数
    li $v0, 4
    la $a0, prompt2
    syscall
    li $v0, 1
    move $a0, $t0
    syscall
    li $v0, 4
    la $a0, prompt3
    syscall
    
    # 获取输入字符串
    li $v0, 8           
    la $a0, inputString 
    li $a1, 100         
    syscall
    la $t3, inputString 
    
    # 初始化循环变量
    li $t4, 0           # 已读取的整数计数
    li $t6, 0           # 临时存储正在解析的整数
    
getNIntsLoop:
    beq $t4, $t0, endGetNIntsLoop   # 读取完n个整数则退出
    
    lb $t5, 0($t3)      # 读取当前字符
    beq $t5, 31, skipFirstByte # 跳过控制字符
    beq $t5, 32, saveLastInt   # 遇到空格保存当前整数
    beq $t5, 10, saveLastInt   # 遇到回车保存当前整数
    
    # 解析数字字符为整数
    subi $t5, $t5, 48   
    mul $t6, $t6, 10    
    add $t6, $t6, $t5   
    
    addi $t3, $t3, 1    
    j getNIntsLoop
    
skipFirstByte:
    addi $t3, $t3, 1     
    j getNIntsLoop
    
saveLastInt:
    # 保存解析好的整数到数组
    sw $t6, 0($t2)
    
    # 测试打印:确认存储的值
    li $v0, 1
    move $a0, $t6
    syscall
    li $v0, 1
    lw $a0, 0($t2)
    syscall
    li $v0, 4
    la $a0, newLine
    syscall
    
    addi $t2, $t2, 4    # 移动到数组下一个位置
    addi $t3, $t3, 1    # 移动到下一个字符
    li $t6, 0           # 重置临时解析变量
    
    addi $t4, $t4, 1    # 计数+1
    j getNIntsLoop
    
endGetNIntsLoop:
    move $t2, $t7       # 恢复数组基地址到$t2
    
    # 测试打印数组元素
    li $v0, 4
    la $a0, newLine
    syscall
    li $v0, 1
    lw $a0, 0($t2)      # 打印第一个元素
    syscall
    li $v0, 4
    la $a0, newLine
    syscall
    li $v0, 1
    lw $a0, 4($t2)      # 打印第二个元素(如果n>=2)
    syscall
    li $v0, 4
    la $a0, newLine
    syscall
    
    # 初始化求和变量
    li $t5, 0           # $t5存储总和
    li $t4, 0           # 重置计数器为0
    
getSumLoop:
    beq $t4, $t0, endSumLoop    # 遍历完n个元素则退出
    lw $t6, 0($t2)                # 加载当前数组元素
    
    add $t5, $t5, $t6             # 累加到总和
    addi $t2, $t2, 4              # 移动到下一个元素
    addi $t4, $t4, 1              # 计数器+1
    j getSumLoop                  # 继续循环
    
endSumLoop:
    # 打印总和
    li $v0, 4
    la $a0, newLine
    syscall
    li $v0, 1          
    move $a0, $t5      
    syscall            
    
    # 退出程序
    li $v0, 10
    syscall

关键修改点

  1. 保留数组基地址:在分配堆内存后,用$t7保存基地址,避免$t2在存数时递增导致基地址丢失。
  2. 修正字符串存储:将inputString: .word 100改为inputString: .space 100,正确分配字符串存储空间。
  3. 求和循环正向遍历:重置计数器从0开始,正向遍历数组,逻辑更直观,避免反向遍历的混淆。
  4. 修复测试打印:用lw指令加载数组元素的值而非地址,正确打印存储的整数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:23:11