ARM7大端模式下LDR加载字节顺序异常问题求助
问题修复与汇编代码优化方案
核心问题拆解
- 字节序错乱:ARM默认是小端模式,用
LDR加载4字节时,内存中的字符顺序会在寄存器中反转。比如内存里是't' 'h' 'e' ' ',加载后寄存器里会变成0x20656874,直接按原字符顺序匹配必然出错。 - 匹配逻辑漏洞:你需要匹配的是独立的"the"(前后为空格或字符串结束符NULL),但当前代码只检查了
t开头的连续三个字符,没处理边界情况,再加上字节序错误,直接导致匹配失效。 - NULL终止缺失:拷贝完成后未给STRING2添加
0x00终止符,必然会出现输出字符串乱码的问题。
具体修复步骤
1. 解决字节序问题:改用逐字节判断
放弃4字节加载的方式,逐字节检查更稳妥,完全避开小端模式的坑,示例代码片段:
; 假设R0 = STRING1源指针,R1 = STRING2目标指针 LOOP: LDRB R2, [R0], #1 ; 读取当前字符,源指针自动后移 CMP R2, #0x00 ; 先判断是否到字符串末尾 BEQ ADD_NULL CMP R2, #0x74 ; 检查当前字符是否是't' BNE COPY_CHAR ; 不是则直接拷贝到目标 ; 检查下一个字符是否是'h' LDRB R3, [R0] CMP R3, #0x68 BNE ROLLBACK_T ; 不是则回退指针,单独拷贝't' ; 检查第三个字符是否是'e' LDRB R4, [R0, #1] CMP R4, #0x65 BNE ROLLBACK_TH ; 不是则回退指针,拷贝't'+'h' ; 检查"the"后续是否是空格或NULL(确保是独立单词) LDRB R5, [R0, #2] CMP R5, #0x20 BEQ SKIP_THE CMP R5, #0x00 BEQ SKIP_THE ; 不是独立的"the",拷贝三个字符 ROLLBACK_TH: STRB R3, [R1], #1 ROLLBACK_T: STRB R2, [R1], #1 B LOOP SKIP_THE: ADD R0, R0, #2 ; 跳过'h'和'e',源指针已移过't' B LOOP COPY_CHAR: STRB R2, [R1], #1 ; 拷贝当前字符到目标字符串 B LOOP ADD_NULL: STRB R2, [R1] ; 给目标字符串添加NULL终止符
2. 完善边界匹配逻辑
针对字符串开头就是"the"的情况(比如"the apple"),需要单独处理,避免不必要的前置空格检查:
; 提前处理开头的"the" LDRB R2, [R0] CMP R2, #0x74 BNE LOOP LDRB R3, [R0, #1] CMP R3, #0x68 BNE LOOP LDRB R4, [R0, #2] CMP R4, #0x65 BNE LOOP LDRB R5, [R0, #3] CMP R5, #0x20 BEQ SKIP_FIRST_THE CMP R5, #0x00 BEQ SKIP_FIRST_THE B LOOP SKIP_FIRST_THE: ADD R0, R0, #3 B LOOP
3. 强制添加NULL终止符
只要遍历到STRING1的NULL结束符,立刻给STRING2写入NULL,这一步是字符串处理的必要操作,必须执行,否则会出现内存溢出或乱码。
调试小技巧
- 单步执行时,紧盯寄存器和内存窗口,检查每次
LDRB/STRB操作后的数据和指针变化是否符合预期。 - 如果坚持要用4字节加载匹配,记得用
REV指令反转字节序,让寄存器内的字节顺序和内存一致:
LDR R2, [R0] REV R2, R2 ; 反转后寄存器字节顺序与内存一致 CMP R2, #0x74686520 ; 匹配"the " BEQ SKIP_THE
内容的提问来源于stack exchange,提问作者salkh08
相关产品推荐
相关产品推荐

