MIPS字符串长度统计代码异常排查(QTSPIM环境运行)
问题诊断与修复方案
兄弟,你的问题完全出在循环退出条件上,和字符串末尾的\0无关——毕竟你用了.asciiz声明字符串,QTSPIM会自动在末尾加上终止符\0的,这点不用怀疑。
错误根源分析
看你循环里的退出判断:
beqz $t0, print # if \0 is found print and exit
这行代码是在检查字符串的地址寄存器$t0是否为0,但$t0是从my_string的起始地址开始不断加1的,永远不会变成0,自然会一直循环下去,直到越界访问内存,这就是为什么程序停不下来的原因。你应该检查的是当前读取的字符是否为终止符\0,而不是地址本身。
修复后的完整代码
我帮你调整了逻辑,关键修改处标了注释:
.data endl: .asciiz "\n" my_string: .asciiz "thisisastring" star: .asciiz "*" str_end: .word 0 space: .asciiz " " .text .globl main main: la $a0, my_string li $v0, 4 syscall la $a0, endl li $v0, 4 syscall la $t0, my_string # load mystring base address to $t0 li $t4, 0 # character counter cont: lb $t2, ($t0) # 先加载当前字符到$t2 beqz $t2, print # 检查当前字符是否为\0,是则退出循环(核心修改!) addi $t4, $t4, 1 # 字符计数+1 lbu $a0, ($t0) # 打印当前字符 li $v0, 11 syscall addi $t0, $t0, 1 # 移动到下一个字符地址 j cont print: la $a0, endl # 先换行,让计数结果更清晰 li $v0, 4 syscall move $a0, $t4 li $v0, 1 syscall exit: li $v0, 10 syscall
关键修改说明
- 调整循环逻辑顺序:先加载当前字符到
$t2,判断是否为\0,再执行计数和打印操作,这样不会把终止符\0也算入字符总数。 - 修正退出判断条件:把
beqz $t0, print改成beqz $t2, print,现在判断的是当前读取的字符是否为终止符,符合字符串处理的标准逻辑。
现在你在QTSPIM里运行这段代码,就能正常统计并打印字符数,循环也会在字符串末尾正确退出啦。
内容的提问来源于stack exchange,提问作者George Sp
相关产品推荐
相关产品推荐

