点击查看代码
// 基于32位系统分析
#define lsize sizeof(word) // sizeof(word) == 4
// 为什么是lsize - 1?32位系统4字节对齐,地址跨度是0x0, 0x4, 0x8,0xC......
// 所以4字节对齐的地址,最低两个bit都是0,如果给定地址最低两个bit不是0,则该地址不是字节对齐
#define lmask (lsize - 1) // 0x03 (32位系统) 0x07 (64位系统)
void *memcpy(void *dest, const void *src, size_t count) {
char *d = (char *)dest;
const char *s = (const char *)src;
int len;
if (count == 0 || dest == src)
return dest;
// 判断是目的地址和源地址是否是地址对齐
if (((long)d | (long)s) & lmask) {
// src and/or dest do not align on word boundary
if ((((long)d ^ (long)s) & lmask) || (count < lsize))
len = count; // copy the rest of the buffer with the byte mover
else
// 如果目标地址不是按 word 大小对齐,计算需要复制到下一个对齐边界的字节数
len = lsize - ((long)d & lmask); // move the ptrs up to a word boundary
// 减去按字节复制的数据长度,剩余的可按照word进行处理的数据长度
count -= len;
// 按字节复制数据
for (; len > 0; len--)
*d++ = *s++;
}
// 按word复制数据
for (len = count / lsize; len > 0; len--) {
*(word *)d = *(word *)s;
d += lsize;
s += lsize;
}
// 剩余的数据长度不满4字节,按字节复制数据
for (len = count & lmask; len > 0; len--)
*d++ = *s++;
return dest;
}