如何用lw/sw替代sb/lb处理字符串?内存对齐相关疑问
用lw/sw实现字符串特殊字符过滤的核心思路
整体逻辑框架
因为要求用lw/sw(每次操作4字节)而非单字节指令,核心是把4字节块拆成单个字符判断,再将合法字符重新拼接成4字节块写入内存:
- 批量读取:每次用
lw从输入缓冲区加载4字节到寄存器,同时移动输入指针。 - 字符拆分判断:把寄存器中的4字节逐一拆成单个字符(用
srl右移+andi取低8位),检查是否属于需要移除的特殊字符集合。 - 拼接存储:将合法字符逐个拼入目标寄存器(用
sll左移腾位+or合并字符),攒够4字节就用sw写入输出数组;若到字符串结尾,处理剩余字符并补\0。
内存对齐问题解决
lw/sw要求操作的内存地址必须是4字节对齐(地址低两位为0),否则会触发架构异常:
- 声明输入/输出数组时,强制4字节对齐:汇编里用
.align 2(2^2=4),C代码里用__attribute__((aligned(4))) char output[1024];。 - 如果输入字符串起始地址不对齐(作业场景一般不会出现),可以先用
lb处理前1-3个字节到对齐位置,再切换到lw批量处理——教授要求主要用lw/sw,所以重点保证数组本身是对齐的即可。
字符拆分与拼接的具体操作
- 拆分4字节块:假设寄存器
t0存了4个字符(大端模式下,高位字节是第一个字符):# 取第一个字符(最高位字节) srl t2, t0, 24 # 右移24位,把最高位字节移到低8位 andi t2, t2, 0xff # 保留低8位,得到单个字符 # 取第二个字符 srl t3, t0, 16 andi t3, t3, 0xff # 以此类推处理第三、第四个字符 - 拼接合法字符:用寄存器
t1作为临时拼接容器,初始值为0:
每拼接一个字符计数一次,计数到4时,用# 假设有合法字符存在t2中 sll t1, t1, 8 # t1左移8位,腾出低8位空间 or t1, t1, t2 # 把合法字符合并到t1的低8位sw把t1写入输出数组,然后重置t1和计数。
收尾处理
当遇到字符串结束符\0时,停止批量读取:
- 如果
t1里还有1-3个未写入的合法字符,直接将t1写入内存(后面的字节会是0,不影响字符串,因为最后要补\0);或者把\0拼入t1后再sw,确保字符串正确终止。
内容的提问来源于stack exchange,提问作者MOOSE
相关产品推荐
相关产品推荐

