问题描述
我正在使用 arm-none-eabi 版本的 gcc 在 ARM cortex-m MCU 上工作。我也在使用 -fnostdlib
和 -fnostdin
。
在我的代码中,我使用了 memcpy
和 strlen
。根据 gcc 手册,这两个函数都是内置函数。当我按原样或按 __buitin_...
使用这些函数时,我得到 undefined reference to ...
。
解决方法
内置函数不是真正的函数。编译器可以自由地用“正常”函数调用替换它们。 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