两三年前的一篇笔记,挺有意思的。
[ glibc-2.12.2 ] 中memcpy()的源码,加上个别中文注释:
// 位于 string/memcpy.c
#include <string.h>
#include <memcopy.h>
#include <pagecopy.h>
#undef memcpy
void *
memcpy (dstpp, srcpp, len)
void *dstpp;
const void *srcpp;
size_t len;
{
unsigned long int dstp = (long int) dstpp; //目的地址
unsigned long int srcp = (long int) srcpp; //源地址
/* Copy from the beginning to the end. */
/* If there not too few bytes to copy, use word copy. */
if (len >= OP_T_THRES) /* 根据不同情况,OP_T_THRES定义为16或8。 */
{
/* Copy just a few bytes to make DSTP aligned. */
/* 补码的余数 -- 算出dstp与离的最近一个对齐地址之间的距离。*/
len -= (-dstp) % OPSIZ;
BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
/* Copy whole pages from SRCP to DSTP by virtual address manipulation,
as much as possible. */
// 对于特殊平台可能使用虚拟页拷贝。i386不支持,空的
PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
/* Copy from SRCP to DSTP taking advantage of the known alignment of
DSTP. Number of bytes remaining is put in the third argument,
i.e. in LEN. This number may vary from machine to machine. */
WORD_COPY_FWD (dstp, srcp, len, len);
/* Fall out and copy the tail. */
}
/* There are just a few bytes to copy. Use byte memory operations. */
BYTE_COPY_FWD (dstp, srcp, len);
return dstpp;
}
libc_hidden_builtin_def (memcpy)
范围为[0,M)的整数计量系统,其模为M。若 a + b = M,则a与b互为补数。
可以考虑8位二进制数,M为2^8=256。若a = 17,则 a的补数: b = 239。
uint16_t val = 17; 则无符号的val加一个负号变成它的补数:-val=256-17=239,按4字节对齐 239 % 4 = 3.
17离的最近的两个对齐地址分别是16,20,与16的距离:val%4==1

本文深入探讨了glibc中的memcpy与memmove函数源码,详细解释了如何优化字节拷贝过程,包括对齐拷贝、字节块拷贝及处理内存重叠的情况。通过对i386平台上的具体实现分析,揭示了高效内存拷贝背后的原理。
1406

被折叠的 条评论
为什么被折叠?



