在 arm 中使用 GCC 的内置函数

Inb*_*ong 4 gcc arm built-in

我正在使用没有 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 版本?

chi*_*ill 5

不应使用内置函数来实现自身 :)

内置函数应该在应用程序代码中使用 - 那么编译器可能会也可能不会生成一些特殊的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)