我正在使用没有 libc 的裸机工具链开发 cortex-m3 板。
我实现了 memcpy,它逐字节复制数据,但它太慢了。在 GCC 手册中,它说它提供了 __builtin_memcpy,我决定使用它。所以这里是 __builtin_memcpy 的实现。
#include <stddef.h>
void *memcpy(void *dest, const void *src, size_t n)
{
return __builtin_memcpy(dest,src,n);
}
Run Code Online (Sandbox Code Playgroud)
当我编译这段代码时,它变成了一个永不结束的递归函数。
$ arm-none-eabi-gcc -march=armv7-m -mcpu=cortex-m3 -mtune=cortex-m3 \
-O2 -ffreestanding -c memcpy.c -o memcpy.o
$ arm-none-eabi-objdump -d memcpy.o
memcpy.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <memcpy>:
0: f7ff bffe b.w 0 <memcpy>
Run Code Online (Sandbox Code Playgroud)
我做错了吗?如何使用编译器生成的 memcpy 版本?
不应使用内置函数来实现自身 :)
内置函数应该在应用程序代码中使用 - 那么编译器可能会也可能不会生成一些特殊的insn 序列或对底层真实函数的调用
相比:
int a [10], b [20];
void
foo ()
{
__builtin_memcpy (a, b, 10 * sizeof (int));
}
Run Code Online (Sandbox Code Playgroud)
这导致:
foo:
stmfd sp!, {r4, r5}
ldr r4, .L2
ldr r5, .L2+4
ldmia r4!, {r0, r1, r2, r3}
mov ip, r5
stmia ip!, {r0, r1, r2, r3}
ldmia r4!, {r0, r1, r2, r3}
stmia ip!, {r0, r1, r2, r3}
ldmia r4, {r0, r1}
stmia ip, {r0, r1}
ldmfd sp!, {r4, r5}
bx lr
Run Code Online (Sandbox Code Playgroud)
但:
void
bar (int n)
{
__builtin_memcpy (a, b, n * sizeof (int));
}
Run Code Online (Sandbox Code Playgroud)
导致调用 memcpy 函数:
bar:
mov r2, r0, asl #2
stmfd sp!, {r3, lr}
ldr r1, .L5
ldr r0, .L5+4
bl memcpy
ldmfd sp!, {r3, lr}
bx lr
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5342 次 |
最近记录: |