中级会员
 
- 积分
- 354
- 金钱
- 354
- 注册时间
- 2018-9-14
- 在线时间
- 157 小时
|
本帖最后由 sppz 于 2020-10-17 09:38 编辑
先看一usub8的行为
可以看到字节溢出则对应的GE位为0
APSR情况如下
字节值下溢时为0对应GE为0再看一下sel行为
通过GE又可以选择该字节的值,这里我们GE=1时0,GE=0时选择1,这样有'\0'时,值才会不为0
代码如下(未经验证),如果有人试了有问题,请告诉我,谢谢- size_t strlen(const char *string)
- {
- const char *data;
- size_t value0, value1, value2;
- data = string;
- while (((size_t)data) % sizeof(void *) != 0)
- {
- if (*data == '\0')
- {
- return data - string;
- }
- ++data;
- }
- value1 = 0x01010101, value2 = 0;
- __asm__(
- "__loop:;\n"
- "ldr %[value0], [%[data]], #4;\n"
- "usub8 %[value0], %[value0], %[value1];\n"
- "sel %[result], %[value2], %[value1];\n"
- "cmp %[result], #0;\n"
- "beq __loop;\n"
- : [result]"=r" (value0)
- : [data]"r" (data), [value0]"r" (value0), [value1]"r" (value1), [value2]"r" (value2)
- :
- );
- if ((value0 & 0xff) != 0)
- {
- return data - string - 4;
- }
- else if ((value0 & 0xff00) != 0)
- {
- return data - string - 3;
- }
- else if ((value0 & 0xff0000) != 0)
- {
- return data - string - 2;
- }
- else
- {
- return data - string - 1;
- }
- }
复制代码
附加汇编,可以看出关键部分效率应该还是很高的
- 08000dc0 strlen:
- 8000dc0: 81 07 lsls r1, r0, #30
- 8000dc2: 01 46 mov r1, r0
- 8000dc4: 1a d0 beq #52 <__loop+0x30>
- 8000dc6: 4f f0 01 32 mov.w r2, #16843009
- 8000dca: 00 23 movs r3, #0
- 08000dcc __loop:
- 8000dcc: 51 f8 04 0b ldr r0, [r1], #4
- 8000dd0: c0 fa 42 f0 usub8 r0, r0, r2
- 8000dd4: a3 fa 82 f2 sel r2, r3, r2
- 8000dd8: 00 2a cmp r2, #0
- 8000dda: f7 d0 beq #-18 <__loop>
- 8000ddc: 08 1a subs r0, r1, r0
- 8000dde: 13 06 lsls r3, r2, #24
- 8000de0: 1c bf itt ne
- 8000de2: 04 38 subne r0, #4
- 8000de4: 70 47 bxne lr
- 8000de6: 12 f4 7f 4f tst.w r2, #65280
- 8000dea: 1c bf itt ne
- 8000dec: 03 38 subne r0, #3
- 8000dee: 70 47 bxne lr
- 8000df0: 12 f4 7f 0f tst.w r2, #16711680
- 8000df4: 14 bf ite ne
- 8000df6: 02 38 subne r0, #2
- 8000df8: 01 38 subeq r0, #1
- 8000dfa: 70 47 bx lr
- 8000dfc: 01 78 ldrb r1, [r0]
- 8000dfe: 02 46 mov r2, r0
- 8000e00: a1 b1 cbz r1, #40
- 8000e02: 51 1c adds r1, r2, #1
- 8000e04: 8b 07 lsls r3, r1, #30
- 8000e06: de d1 bne #-68 <strlen+0x6>
- 8000e08: 0b 78 ldrb r3, [r1]
- 8000e0a: 8b b1 cbz r3, #34
- 8000e0c: 91 1c adds r1, r2, #2
- 8000e0e: 8b 07 lsls r3, r1, #30
- 8000e10: d9 d1 bne #-78 <strlen+0x6>
- 8000e12: 0b 78 ldrb r3, [r1]
- 8000e14: 63 b1 cbz r3, #24
- 8000e16: d1 1c adds r1, r2, #3
- 8000e18: 8b 07 lsls r3, r1, #30
- 8000e1a: d4 d1 bne #-88 <strlen+0x6>
- 8000e1c: 0b 78 ldrb r3, [r1]
- 8000e1e: 3b b1 cbz r3, #14
- 8000e20: 04 32 adds r2, #4
- 8000e22: 91 07 lsls r1, r2, #30
- 8000e24: 07 d1 bne #14 <__loop+0x6a>
- 8000e26: 11 78 ldrb r1, [r2]
- 8000e28: 00 29 cmp r1, #0
- 8000e2a: ea d1 bne #-44 <__loop+0x36>
- 8000e2c: 10 1a subs r0, r2, r0
- 8000e2e: 70 47 bx lr
- 8000e30: 0a 46 mov r2, r1
- 8000e32: 10 1a subs r0, r2, r0
- 8000e34: 70 47 bx lr
- 8000e36: 11 46 mov r1, r2
- 8000e38: c5 e7 b #-118 <strlen+0x6>
复制代码
修正,编译器真就各种负优化...
|
|