ARM 32位下内存子串匹配失败问题排查及正确实现咨询
问题分析与解决方案
错误原因
你踩了ARM32汇编里一个很容易忽略的细节:ldr指令默认加载的是32位字(4字节),而不是单个字节。
当你执行ldr r3,[r0,#0x12]时,它会从地址X+0x12开始连续读取4个字节(覆盖X+0x12到X+0x15),然后按照系统的端序(ARM默认小端)把这4个字节拼成一个32位整数存入r3。比如你要检查的第一个字节是0xAA,但实际r3里存的是0x11CCBBAA(小端模式下),拿这个和0xAA比较自然会失败。
正确实现方法
有两种常见的解决思路,按需选择:
方法1:逐个字节加载比较(最稳妥,不受端序影响)
使用ldrb指令(Load Byte),它会从指定地址读取1个字节,存入寄存器的低8位,高24位自动清零,完美匹配你的逐字节检查需求:
@ 检查X+0x12处的0xAA ldrb r3, [r0, #0x12] cmp r3, #0xAA BNE Error @ 检查X+0x13处的0xBB ldrb r3, [r0, #0x13] cmp r3, #0xBB BNE Error @ 检查X+0x14处的0xCC ldrb r3, [r0, #0x14] cmp r3, #0xCC BNE Error @ 检查X+0x15处的0x11 ldrb r3, [r0, #0x15] cmp r3, #0x11 BNE Error @ 继续检查后续的0x22、0x33、0x44 ldrb r3, [r0, #0x16] cmp r3, #0x22 BNE Error ldrb r3, [r0, #0x17] cmp r3, #0x33 BNE Error ldrb r3, [r0, #0x18] cmp r3, #0x44 BNE Error @ 执行到这里说明子串完全匹配
方法2:批量加载比较(更高效,需注意端序)
如果追求效率,可以一次加载多个字节(半字/字),然后根据系统端序拼接成对应的值比较。比如ARM默认小端模式下:
@ 一次性检查X+0x12到X+0x15的4个字节:0xAA 0xBB 0xCC 0x11 → 小端字为0x11CCBBAA ldr r3, [r0, #0x12] cmp r3, #0x11CCBBAA BNE Error @ 一次性检查X+0x16到X+0x17的2个字节:0x22 0x33 → 小端半字为0x3322 ldrh r3, [r0, #0x16] cmp r3, #0x3322 BNE Error @ 最后检查X+0x18的单个字节0x44 ldrb r3, [r0, #0x18] cmp r3, #0x44 BNE Error @ 子串匹配成功
如果你的系统是大端模式,那么批量加载的比较值要改成对应大端拼接的结果(比如前4字节的大端值是0xAABBCC11)。
内容的提问来源于stack exchange,提问作者Ljohhuh
相关产品推荐
相关产品推荐

