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

MIPS汇编字母统计程序:空格与换行无法输出问题排查

问题分析与修复

问题根源

  1. 数组越界写入破坏字符串常量
    统计循环中,beq $t5, 104, reset的判断放在了sw $s0, array($t5)之后。array是26个word(共104字节),合法偏移范围是0~100(25*4)。当$t5等于104时,执行sw会把数据写到数组之外的内存区域,恰好覆盖了space和nLine这两个字符串常量的内容,导致打印空格和换行时输出空字符串。

  2. 字符串结束判断错误
    原代码用换行符(ASCII 10)判断字符串结束,但string是.asciiz定义的,结尾是null字符(ASCII 0),所以beq $t2, $t3, nArray永远不会触发,统计循环只能靠数组偏移达到104来终止,进一步加剧了越界问题。

修复步骤

  1. 调整统计循环的判断顺序
    将beq $t5, 104, reset移到sw $s0, array($t5)之前,避免数组越界写入。
  2. 修正字符串结束符判断
    将li $t3, 10改为li $t3, 0,用null字符判断字符串结束。

修复后的代码

.data
array:  .word   0:26
space:  .asciiz " "
nLine:  .asciiz "\n"
string: .asciiz "abbcccddddeffggghhhhijjkkkllllmnnoooppppqrrsssttttuvvwwwxxxxyzz"
bye:    .ascii  "\n**** Thank you for running my program ****\n"
        .asciiz "\n**************** Goodbye *****************"

    .text
main:
    addi    $t0, $zero, 0       # clear $t0
    
    li  $t3, 0          # 0 is ASCII for null terminator (string end)
    li  $t4, 97         # 97 is ASCII for 'a'
    li  $s0, 0          # counter for number occurence
    li  $t5, 0          # initiate counter for array position
    la  $t1, string     # load address of string into $t1
    
count:  
    beq $t5, 104, reset     # 先判断是否越界,再执行存储
    sw  $s0, array($t5)     # store letter count in array at position $t5
    
    lb  $t2, ($t1)      # load next character of string
    
    beq $t2, $t3, nArray    # once end of string is reached move to next array element
    
    beq $t2, $t4, inc       # if letter matches, increment count
    
    addi    $t1, $t1, 1     # if letter does not match, move to next character in string
    
    j   count           # loop
    
inc:
    addi    $s0, $s0, 1     # increment count
    
    addi    $t1, $t1, 1     # next character in string

    j   count           # loop
    
nArray:
    addi    $s0, $zero, 0       # clear $s0
    
    la  $t1, string     # load address of string into $t1
    
    addi    $t4, $t4, 1     # move to next ASCII letter
    
    addi    $t5, $t5, 4     # move to next array element
    
    j   count           # loop
    
reset:
    addi    $t0, $zero, 0       # clear $t0
    addi    $t1, $zero, 0       # clear $t1
    addi    $t2, $zero, 0       # clear $t2
    addi    $t3, $zero, 0       # clear $t3
    addi    $t4, $zero, 0       # clear $t4
    addi    $t5, $zero, 0       # clear $t5
    addi    $t6, $zero, 0       # clear $t6
    
printA1:
    beq $t0, 104, done      # once through 26 words, end
    
    beq $t0, 52, printNl    # once through 13 words, print new line
    
printA2:
    lw  $t6, array($t0)     # load next array element
    
    addi    $t0, $t0, 4     # increment array position
    
    li  $v0, 1          # load syscall code for print_int
    move    $a0, $t6        # move array element value into syscall argument
    syscall             # print integer
    
    li  $v0, 4          # load syscall code for print_string
    la  $a0, space      # load space into syscall argument
    syscall             # print space
    
    j   printA1         # loop
    
printNl:
    li  $v0, 4          # load syscall code for print_string
    la  $a0, nLine      # load new line into argument for syscall
    syscall             # print new line
    
    j   printA2         # loop
    
done:
    li  $v0, 4          # system call code for print_string
    la  $a0, bye        # load address of message into $a0
    syscall             # print the string

    li  $v0, 10         # terminate program run and
    syscall             # return control to system

                    # END OF PROGRAM

修复后输出

1 2 3 4 1 2 3 4 1 2 3 4 1 
2 3 4 1 2 3 4 1 2 3 4 1 2 
**** Thank you for running my program ****

**************** Goodbye *****************
-- program is finished running --

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:45:15