memcpy source code c
。该实现是一次复制一个字节的 while 循环。尽管许多答案都清楚地表明,实际实现比一次复制一个字节要快得多。我在哪里可以找到真正的实现,编译器实际使用的真正的、高度优化的实现? C 语言是什么样的?
寻求书籍、工具、软件库等的推荐
其实不然。我问的是现有的实现是如何工作的,而不是我应该使用哪个库等。
定义 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 存活到链接时间,那么链接器被告知要链接的内容就是被链接的内容。
编译器实际使用的一个?
编译器可能会以不同的方式优化
memcpy
,只要副作用保持不变。所以我想这将使两个实现可用,因此编译器可能有一个像“编译时”memcpy
这样的内部实现,而C标准库可能会提供单独的memcpy
实现。
C 语言是什么样的?
C 标准库有许多可用的实现,并且其中每一个都有自己的
memcpy
实现,甚至每一个都可能有(并且具有)不同的实现memcpy
不同的架构。出于优化目的,某些 C 标准库实现有时会在特定架构的汇编中选择实现 memcpy
。例如,您可以找到newlibs generic memcpy或newlib's memcpy for arm in assembly或glibc generic memcpy和glibc i386 memcpy实现。