memcpy的内部实现如何工作?

标准C函数’memcpy’如何工作? 它必须将(大)RAM块复制到RAM中的另一个区域。 因为我知道你不能在汇编中直接从RAM移动到RAM(使用mov指令)所以我猜它在复制时使用CPU寄存器作为中间存储器?

但它是如何复制的? 通过块(如何通过块复制?),按单个字节(char)或它们具有的最大数据类型(复制在long long double中 – 在我的系统上为12个字节)。

编辑: 好吧显然你可以直接将数据从RAM移动到RAM ,我不是汇编专家,所有我学习的汇编都来自这个文档( X86汇编指南 ),在有关你无法从中移动的mov指令的部分中提及RAM到RAM。 显然这不是真的。

要看。 一般情况下,你不能在一个周期内物理复制大于最大可用寄存器的任何东西,但这并不是机器如何工作的。 实际上,你真的不太关心CPU在做什么,而是更关心DRAM的特性。 机器的内存层次结构将以最快的方式执行此副本(例如,您是否正在加载整个缓存行?与复制操作相关的DRAM行的大小是多少?)。 实现可能会选择使用某种向量指令来实现memcpy 。 在没有参考特定实现的情况下,它实际上是具有单位缓冲区的逐字节副本。

这是一篇有趣的文章 ,描述了一个人对优化memcpy的冒险。 主要的观点是,它总是基于您可以低成本执行的指令针对特定的体系结构和环境。

memcpy的实现非常特定于实现它的系统。 实现通常是硬件辅助的。

内存到内存的mov指令并不常见 – 它们至少已经出现了PDP-11次,当你可以编写类似这样的内容时:

  MOV FROM, R2 MOV TO, R3 MOV R2, R4 ADD LEN, R4 CP: MOV (R2+), (R3+) ; "(Rx+)" means "*Rx++" in C CMP R2, R4 BNE CP 

注释行大致相当于C

 *to++ = *from++; 

当代CPU具有直接实现memcpy指令:使用源地址和目标地址加载特殊寄存器,调用内存复制命令,让CPU完成剩下的工作。

memcpy一个简单实现是:

  while (n--) *s2++ = *s1++; 

但是glibc通常在汇编代码中使用一些聪明的实现。 memcpy调用通常是内联的。

在x86上,代码检查size参数是2的字面倍数还是4的倍数(使用gcc内置函数)并使用带有movl指令的循环(复制4个字节),否则它调用一般情况。

一般情况使用repmovsl指令使用快速块复制程序集。