使用栈移除字符串元音失败:MIPS代码调试求助
MIPS汇编移除字符串元音失败的问题修复
核心错误分析
- 逻辑分支完全失效:原代码中仅在字符为元音时跳转到
vowel标签,但辅音字符会直接执行vowel标签后的逻辑——所有字符都会被压栈,完全没有实现元音过滤。 - 索引计算错误:
end标签处的addiu $t1, -2会跳过最后一个有效字符。原遍历逻辑结束时,$t1指向字符串末尾的NUL字符,只需减1就能回到最后一个有效字符的索引。 - 内存写入错误:
popl循环中用sw(存储字)写入单字符,会一次性覆盖4字节内存,破坏后续缓冲区内容,应该使用sb(存储字节)。 - 元音处理逻辑颠倒:原代码中元音字符也被执行压栈操作,正确逻辑应为仅压入辅音,元音直接跳过。
修正后的代码
.text .globl main main: li $v0, 4 la $a0, prompt # 提示用户输入字符串 syscall li $v0, 8 # 将字符串存储到str缓冲区 la $a0, str li $a1, 120 syscall li $t4, 0 li $t1, 0 addiu $sp, $sp, -4 # 压入一个NUL字节作为栈底标记 sw $zero, ($sp) loop: lbu $t0, str($t1) beqz $t0, end # 遇到NUL字符,结束遍历 addiu $t1, $t1, 1 # 索引自增,继续遍历 j loop end: addiu $t1, $t1, -1 # 回退到最后一个有效字符的索引 loop2: beq $t1, $t4, end2 # 索引到0,结束遍历 lbu $t0, str($t1) # 判断是否为元音 li $t5, 'a' beq $t5, $t0, skip_vowel li $t5, 'e' beq $t5, $t0, skip_vowel li $t5, 'i' beq $t5, $t0, skip_vowel li $t5, 'o' beq $t5, $t0, skip_vowel li $t5, 'u' beq $t5, $t0, skip_vowel # 辅音字符:压入栈 addiu $sp, $sp, -4 sw $t0, ($sp) skip_vowel: addiu $t1, $t1, -1 # 索引递减 j loop2 end2: li $t1, 0 # 重置索引,准备写入结果 popl: lw $t0, ($sp) addiu $sp, $sp, 4 beqz $t0, done # 遇到栈底NUL,结束弹出 sb $t0, str($t1) # 存储单个字节到缓冲区 addiu $t1, $t1, 1 # 索引自增 j popl done: sb $zero, str($t1) # 在结果末尾添加NUL终止符 li $v0, 4 # 输出处理后的字符串 la $a0, str syscall li $v0, 10 # 退出程序 syscall .data prompt: .asciiz "enter a word: " str: .space 128
关键修正点
- 调整
end处的索引计算,确保从最后一个有效字符开始处理 - 新增
skip_vowel标签,元音字符仅递减索引不压栈,辅音字符才执行压栈操作 - 用
sb替代sw写入单字符,避免破坏内存 - 在
done处添加NUL终止符,保证输出字符串的有效性
内容的提问来源于stack exchange,提问作者oscamosca_
相关产品推荐
相关产品推荐

