标准C函数'memcpy'如何工作?它必须将(大)RAM块复制到RAM中的另一个区域。因为我知道你不能在汇编中直接从RAM移动到RAM(使用mov指令)所以我猜它在复制时使用CPU寄存器作为中间存储器?
但它如何复制?通过块(如何通过块复制?),按单个字节(char)或它们拥有的最大数据类型(复制在long long double中 - 在我的系统上为12个字节)。
编辑:显然你可以直接将数据从RAM移动到RAM ,我不是汇编专家,我所学的关于汇编的所有内容都来自这个文件(X86 assembly guide)在关于mov指令的部分中,您无法从RAM移动到RAM。显然这不是真的。
答案 0 :(得分:18)
取决于。一般情况下,你不能在一个周期内物理复制大于最大可用寄存器的任何东西,但这并不是机器如何工作的。实际上,你真的不关心CPU在做什么,而是更关心DRAM的特性。机器的内存层次结构将以尽可能最快的方式执行此副本(例如,您是否正在加载整个缓存行?与复制操作相关的DRAM行的大小是多少?)。实现可能会选择使用某种向量指令来实现memcpy
。在没有参考具体实现的情况下,它实际上是一个具有一位缓冲区的逐字节复制。
Here's a fun article描述了一个人对优化memcpy
的冒险。主要的观点是,它总是会根据您可以低成本执行的指令针对特定的体系结构和环境。
答案 1 :(得分:8)
memcpy
的实现非常特定于实现它的系统。实现通常是硬件辅助的。
内存到内存的移动指令并不常见 - 它们至少在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完成其余操作。
答案 2 :(得分:5)
memcpy
的一个简单实现是:
while (n--) *s2++ = *s1++;
但glibc
通常在汇编代码中使用一些聪明的实现。 memcpy
来电通常是内联的。
在x86上,代码检查size参数是2
的字面倍数还是4
的倍数(使用gcc
内置函数)并使用{{1}的循环指令(复制movl
字节),否则调用一般情况。
一般情况使用4
和rep
指令使用快速块复制程序集。