MIPS架构下用sw/lw指令实现字符读写过滤的故障排查
核心问题定位
原lb/sb版本仅单字节处理字符,逻辑简单不易出错;改用sw/lw打包/读取4字节word后,当前两个字节为非法字符时输出畸形,大概率是字节拆分逻辑错误、脏数据未处理或字节序匹配问题导致。
具体排查方向
字节拆分的移位与掩码错误
用lw读取word后,逐字节提取时必须通过移位+掩码确保仅保留目标8位:- 大端序下,第1个字节(最高位):
srl $t2, $t1, 24 - 第2个字节:
srl $t2, $t1, 16后必须加andi $t2, $t2, 0xff - 第3个字节:
srl $t2, $t1, 8后加andi $t2, $t2, 0xff - 第4个字节:
andi $t2, $t1, 0xff
如果省略掩码,高位的非法字符残留会导致提取的字节值异常,过滤逻辑失效,输出乱码。
- 大端序下,第1个字节(最高位):
字节序不匹配
MIPS为大端架构,打包word时需按输入顺序左移拼接(先输入的字符存在word高位)。若打包时用右移拼接(小端逻辑),拆分时又按大端提取,会导致字节顺序完全颠倒,过滤后输出畸形。未处理非4倍数输入的脏数据
当输入字符数不是4的倍数时,最后一个word的剩余字节是内存脏数据。lb/sb版本仅处理有效字节,而sw会将整个word(含脏数据)存入内存。若读取过滤时未记录有效字节数,会把脏数据当成有效字符处理,尤其当前两个字节非法时,脏数据直接输出导致畸形。终止符处理缺失
原lb/sb版本可能在输入结束后写入\0作为终止符,但sw/lw版本若未将终止符正确打包进word,或读取时未识别终止符,会导致程序越界读取后续内存的脏word,输出乱码。
代码检查要点
打包逻辑验证
检查打包word的代码是否按大端序拼接:# 正确的大端打包示例 sll $t1, $t1, 8 # 左移8位腾出低位空间 or $t1, $t1, $v0 # 将新字符存入低位若此处用右移拼接,字节顺序会完全错误。
过滤逻辑验证
检查提取字节时是否加了andi $t2, $t2, 0xff掩码,确保每个提取的字节是纯8位值,无高位残留。剩余字节处理
输入结束时,若剩余未打包的字节数不为0,需记录该数量,读取对应word时仅处理前N个有效字节,忽略后面的脏数据。终止符设置
输入结束后,需将终止符\0打包进word(若剩余字节数不足4,补0后存入),读取时遇到\0立即停止输出。
内容的提问来源于stack exchange,提问作者coolAid

