GCC 找不到内置的 memcpy

问题描述

我正在使用 arm-none-eabi 版本的 gcc 在 ARM cortex-m MCU 上工作。我也在使用 -fnostdlib-fnostdin

在我的代码中,我使用了 memcpystrlen。根据 gcc 手册,这两个函数都是内置函数。当我按原样或按 __buitin_... 使用这些函数时,我得到 undefined reference to ...

为什么 gcc 没有按预期生成代码

解决方法

内置函数不是真正的函数。编译器可以自由地用“正常”函数调用替换它们。 ARM b 如本例所示:

void *m(void *a,void *b,size_t size)
{
    return __builtin_memcpy(a,b,size);
}

void *m1(void *a,void *b)
{
    return __builtin_memcpy(a,16);
}

void *m2(void *a,200);
}


volatile int a[1000],b[10000],c[1000];


int main(void)
{
    m((void *)a,(void *)b,16);
    __asm(":::m");
    m((void *)a,(void *)c,400);
}

生成的代码将取决于 ARM 架构(如果不对齐的访问是合法的)。

CORTEX-M4                                            CORTEX-M0
m:                                                   m:
  b memcpy                                                   push    {r4,lr}
m1:                                                          bl      memcpy
  push {r4,r5}                                              pop     {r4,pc}
  ldr r5,[r1] @ unaligned                           m1:
  ldr r4,[r1,#4] @ unaligned                               push    {r4,lr}
  ldr r2,#8] @ unaligned                               movs    r2,#16
  ldr r1,#12] @ unaligned                              bl      memcpy
  str r1,[r0,#12] @ unaligned                              pop     {r4,pc}
  str r5,[r0] @ unaligned                           m2:
  str r4,lr}
  str r2,#200
  pop {r4,r5}                                               bl      memcpy
  bx lr                                                      pop     {r4,pc}
m2:                                                  main:
  movs r2,#200                                              ldr     r0,.L6
  b memcpy                                                   push    {r4,r5,r6,lr}
main:                                                        movs    r2,r0
  push {r4,lr}                                              ldr     r3,.L6+4
  ldr r3,.L8                                                ldmia   r3!,{r1,r4,r5}
  ldr r4,.L8+4                                              stmia   r2!,r5}
  ldm r3,{r0,r1,r2,r3}                                   ldr     r3,[r3]
  stm r4,r3}                                   str     r3,[r2]
  :::m                                                       :::m
  mov r2,#400                                               movs    r2,#200
  mov r0,r4                                                 ldr     r1,.L6+8
  ldr r1,.L8+8                                              lsls    r2,#1
  bl memcpy                                                  bl      memcpy
  movs r0,#0                                                movs    r0,#0
  pop {r4,pc}                                               pop     {r4,pc}
.L8:                                                 .L6:
  .word b                                                    .word   a
  .word a                                                    .word   b
  .word c                                                    .word   c
  

https://godbolt.org/z/fh68cv