在ARM MCU上用较小的代码替换memcpy和.divsi3\u skip\u div0\u测试
我的条目包括两个巨大的函数,它们不是由我编写的任何C代码生成的在ARM MCU上用较小的代码替换memcpy和.divsi3\u skip\u div0\u测试,arm,libc,Arm,Libc,我的条目包括两个巨大的函数,它们不是由我编写的任何C代码生成的 000004e4 <.divsi3_skip_div0_test>: 4e4: b410 push {r4} 4e6: 1c04 adds r4, r0, #0 4e8: 404c eors r4, r1 4ea: 46a4 mov ip, r4 4ec: 2301 movs r3, #1 4ee
000004e4 <.divsi3_skip_div0_test>:
4e4: b410 push {r4}
4e6: 1c04 adds r4, r0, #0
4e8: 404c eors r4, r1
4ea: 46a4 mov ip, r4
4ec: 2301 movs r3, #1
4ee: 2200 movs r2, #0
4f0: 2900 cmp r1, #0
4f2: d500 bpl.n 4f6 <.divsi3_skip_div0_test+0x12>
4f4: 4249 negs r1, r1
4f6: 2800 cmp r0, #0
4f8: d500 bpl.n 4fc <.divsi3_skip_div0_test+0x18>
4fa: 4240 negs r0, r0
4fc: 4288 cmp r0, r1
4fe: d32c bcc.n 55a <.divsi3_skip_div0_test+0x76>
500: 2401 movs r4, #1
502: 0724 lsls r4, r4, #28
504: 42a1 cmp r1, r4
506: d204 bcs.n 512 <.divsi3_skip_div0_test+0x2e>
508: 4281 cmp r1, r0
50a: d202 bcs.n 512 <.divsi3_skip_div0_test+0x2e>
50c: 0109 lsls r1, r1, #4
50e: 011b lsls r3, r3, #4
510: e7f8 b.n 504 <.divsi3_skip_div0_test+0x20>
512: 00e4 lsls r4, r4, #3
514: 42a1 cmp r1, r4
516: d204 bcs.n 522 <.divsi3_skip_div0_test+0x3e>
518: 4281 cmp r1, r0
51a: d202 bcs.n 522 <.divsi3_skip_div0_test+0x3e>
51c: 0049 lsls r1, r1, #1
51e: 005b lsls r3, r3, #1
520: e7f8 b.n 514 <.divsi3_skip_div0_test+0x30>
522: 4288 cmp r0, r1
524: d301 bcc.n 52a <.divsi3_skip_div0_test+0x46>
526: 1a40 subs r0, r0, r1
528: 431a orrs r2, r3
52a: 084c lsrs r4, r1, #1
52c: 42a0 cmp r0, r4
52e: d302 bcc.n 536 <.divsi3_skip_div0_test+0x52>
530: 1b00 subs r0, r0, r4
532: 085c lsrs r4, r3, #1
534: 4322 orrs r2, r4
536: 088c lsrs r4, r1, #2
538: 42a0 cmp r0, r4
53a: d302 bcc.n 542 <.divsi3_skip_div0_test+0x5e>
53c: 1b00 subs r0, r0, r4
53e: 089c lsrs r4, r3, #2
540: 4322 orrs r2, r4
542: 08cc lsrs r4, r1, #3
544: 42a0 cmp r0, r4
546: d302 bcc.n 54e <.divsi3_skip_div0_test+0x6a>
548: 1b00 subs r0, r0, r4
54a: 08dc lsrs r4, r3, #3
54c: 4322 orrs r2, r4
54e: 2800 cmp r0, #0
550: d003 beq.n 55a <.divsi3_skip_div0_test+0x76>
552: 091b lsrs r3, r3, #4
554: d001 beq.n 55a <.divsi3_skip_div0_test+0x76>
556: 0909 lsrs r1, r1, #4
558: e7e3 b.n 522 <.divsi3_skip_div0_test+0x3e>
55a: 1c10 adds r0, r2, #0
55c: 4664 mov r4, ip
55e: 2c00 cmp r4, #0
560: d500 bpl.n 564 <.divsi3_skip_div0_test+0x80>
562: 4240 negs r0, r0
564: bc10 pop {r4}
566: 4770 bx lr
568: 2800 cmp r0, #0
56a: d006 beq.n 57a <.divsi3_skip_div0_test+0x96>
56c: db03 blt.n 576 <.divsi3_skip_div0_test+0x92>
56e: 2000 movs r0, #0
570: 43c0 mvns r0, r0
572: 0840 lsrs r0, r0, #1
574: e001 b.n 57a <.divsi3_skip_div0_test+0x96>
576: 2080 movs r0, #128 ; 0x80
578: 0600 lsls r0, r0, #24
57a: b407 push {r0, r1, r2}
57c: 4802 ldr r0, [pc, #8] ; (588 <.divsi3_skip_div0_test+0xa4>)
57e: a102 add r1, pc, #8 ; (adr r1, 588 <.divsi3_skip_div0_test+0xa4>)
580: 1840 adds r0, r0, r1
582: 9002 str r0, [sp, #8]
584: bd03 pop {r0, r1, pc}
586: 46c0 nop ; (mov r8, r8)
588: 00000019 .word 0x00000019
或者,有没有办法告诉gcc在复制结构时不要使用memcpy?(它们是10个字节,所以三条拇指指令应该可以完成这项工作。)我已经尝试添加-mno memcpy
和-Wa,mno memcpy
,但两者都无法识别
更新:
我已经解决了这个问题的memcpy部分-添加一个部分但足够的memcpy函数可以阻止添加另一个
size_t memcpy(uint8_t *restrict dst, uint8_t *restrict const src, size_t size) {
int i;
for (i = 0; i < size; i++) {
dst[i] = src[i];
}
return i;
}
size_t memcpy(uint8_t*限制dst、uint8_t*限制常量src、size_t size){
int i;
对于(i=0;i
它更小,但效率更低,不会处理dst
重叠
000003ec <memcpy>:
3ec: b510 push {r4, lr}
3ee: 2300 movs r3, #0
3f0: 4293 cmp r3, r2
3f2: d003 beq.n 3fc <memcpy+0x10>
3f4: 5ccc ldrb r4, [r1, r3]
3f6: 54c4 strb r4, [r0, r3]
3f8: 3301 adds r3, #1
3fa: e7f9 b.n 3f0 <memcpy+0x4>
3fc: 1c18 adds r0, r3, #0
3fe: bd10 pop {r4, pc}
000003ec:
3ec:b510推送{r4,lr}
3ee:2300 movs r3,#0
3f0:4293凸轮轴位置r3,r2
3f2:d003 beq.n 3fc
3f4:5ccc ldrb r4[r1,r3]
3f6:54c4 strb r4[r0,r3]
3f8:3301加上r3,#1
3fa:e7f9 b.n 3f0
3fc:1c18加上r0、r3和#0
3fe:bd10 pop{r4,pc}
为了澄清这一点,我现在只想问我可以做些什么,用效率更低但更小的代码替换.divsi3\u skip\u div0\u测试
我不清楚这段代码的源代码在哪里,或者如何编辑它的源代码。它看起来比memcpy
更复杂,因为它看起来不像一个C函数,因为它的名字以一个
开头,“它不是从我编写的任何C代码中生成的”-你确定你的代码和你链接的每一个代码,绝对不包含任何整数/
或%
运算符吗?@不象是这样,我使用的是/
,但我自己没有编写.divsi3\u skip\u div0\u test
。我知道没有硬件分割指令的MCU必须在软件中实现它,但我想要一个更小、效率更低的实现。我不明白.divsi3\u skip\u div0\u test
的源代码在哪里,以便我可以修改它并重新生成。它是GNU libc中手工编码的汇编函数吗?根据猜测,尝试覆盖\uu aeabi_idiv()
和适当的朋友怎么样?@不太可能,谢谢,我没有遇到运行时ABI覆盖。如果你回答这个问题,我会接受它。“它不是由我写的任何C代码生成的”-你确定你的代码,以及你链接的每一位代码,绝对不包含任何整数/
或%
运算符吗?@不象是的,我使用的是/
,但是我自己没有写.divsi3\u skip\u div0\u test
。我知道没有硬件分割指令的MCU必须在软件中实现它,但我想要一个更小、效率更低的实现。我不明白.divsi3\u skip\u div0\u test
的源代码在哪里,以便我可以修改它并重新生成。它是GNU libc中手工编码的汇编函数吗?根据猜测,尝试覆盖\uu aeabi_idiv()
和适当的朋友怎么样?@不太可能,谢谢,我没有遇到运行时ABI覆盖。如果你回答这个问题,我会接受的。
size_t memcpy(uint8_t *restrict dst, uint8_t *restrict const src, size_t size) {
int i;
for (i = 0; i < size; i++) {
dst[i] = src[i];
}
return i;
}
000003ec <memcpy>:
3ec: b510 push {r4, lr}
3ee: 2300 movs r3, #0
3f0: 4293 cmp r3, r2
3f2: d003 beq.n 3fc <memcpy+0x10>
3f4: 5ccc ldrb r4, [r1, r3]
3f6: 54c4 strb r4, [r0, r3]
3f8: 3301 adds r3, #1
3fa: e7f9 b.n 3f0 <memcpy+0x4>
3fc: 1c18 adds r0, r3, #0
3fe: bd10 pop {r4, pc}