定义 C 库不是编译器的工作。 C 库函数是 C 库的职责。例如,gcc 负责诸如软浮点函数之类的事情,以便可以针对特定目标完全实现该语言。作为编译器的核心 stdint.h 函数定义了语言特定变量类型(char、short、int 等)的大小,而 stdint.h 是从中派生的,因此只有编译器可以定义这些。
但是 C 库项目、引导程序、链接器脚本和所有 C 库函数、printf()、memcpy() 等。至少在 gnu 世界中,编译器、汇编器/链接器、C 库等是单独的项目,例如,您可以混合使用 gcc、binutils 和 glibc,或者您可以改用 gcc、binutils 和 newlib。并且没有理由期望 glibc 和 newlib 或任何其他 C 库具有相同的 memcpy 实现。
可以集成其他工具链和库。
当然你可以用一行 memcpy(...) 编译成一个简单的测试程序然后反汇编它。
memcpy 是一个特殊的交易,因为一些编译器会生成一个 memcpy,有时也可能以其他方式删除 memcpy 并用一些指令替换它。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned int fun ( unsigned int *x )
{
unsigned int y;
memcpy(&y,x,sizeof(unsigned int));
return(y);
}
Disassembly of section .text:
0000000000000000 <fun>:
0: 8b 07 mov (%rdi),%eax
2: c3 retq
typedef struct
{
unsigned int ui[37];
unsigned short us[33];
unsigned char uc[31];
} HELLO;
HELLO one;
void fun ( HELLO two )
{
one=two;
}
00000000 <fun>:
0: e24dd010 sub sp, sp, #16
4: e92d4010 push {r4, lr}
8: e28dc008 add ip, sp, #8
c: e88c000f stm ip, {r0, r1, r2, r3}
10: e1a0100c mov r1, ip
14: e3a020f8 mov r2, #248 ; 0xf8
18: e59f000c ldr r0, [pc, #12] ; 2c <fun+0x2c>
1c: ebfffffe bl 0 <memcpy>
20: e8bd4010 pop {r4, lr}
24: e28dd010 add sp, sp, #16
28: e12fff1e bx lr
2c: 00000000 .word 0x00000000
并且一些编译器可以选择请求/要求它们不插入 memcpy 或您没有要求的其他库函数。
如果 memcpy 在链接时间内仍然存在,那么链接器被告知链接的内容就是链接的内容。