maillist上有人問關(guān)于這個(gè)函數(shù)的問題,回復(fù)中有人推薦去看它的源代碼
memcpy調(diào)用了__memcpy函數(shù)執(zhí)行內(nèi)存的復(fù)制(__memcpy3d就先不管了),下面是這個(gè)這兩個(gè)函數(shù)的代碼
void *memcpy(void *to, const void *from, size_t n)
{
#ifdef CONFIG_X86_USE_3DNOW
return __memcpy3d(to, from, n);
#else
return __memcpy(to, from, n);
#endif
}

static __always_inline void * __memcpy(void * to, const void * from, size_t n)
{
int d0, d1, d2;
__asm__ __volatile__(
"rep ; movsl\n\t"
"movl %4,%%ecx\n\t"
"andl $3,%%ecx\n\t"
#if 1 /* want to pay 2 byte penalty for a chance to skip microcoded rep? */
"jz 1f\n\t"
#endif
"rep ; movsb\n\t"
"1:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n/4), "g" (n), "1" ((long) to), "2" ((long) from)
: "memory");
return (to);
}
看了一本內(nèi)聯(lián)匯編的書,總算把這段代碼搞懂了。
起始時(shí),把n/4保存在%ecx寄存器中,并把to和from的地址分別存入%edi和%esi (引用占位符)
然后重復(fù)調(diào)用movsl n/4次,接下來應(yīng)該還有(n mod 4)個(gè)字節(jié)尚未復(fù)制,這里用了一個(gè)比較巧妙的方法
movl %4, %%ecx 把n的值保存到%ecx
andl $3, %%ecx n與3做邏輯與,得到n mod 4
jz 1f 如果4 | n,跳過后面的復(fù)制
rep movsb 再?gòu)?fù)制(n mod 4)個(gè)字節(jié)
由于是按四個(gè)字節(jié)復(fù)制的,因此效率上memcpy肯定比strcpy高不少。
memcpy調(diào)用了__memcpy函數(shù)執(zhí)行內(nèi)存的復(fù)制(__memcpy3d就先不管了),下面是這個(gè)這兩個(gè)函數(shù)的代碼


























看了一本內(nèi)聯(lián)匯編的書,總算把這段代碼搞懂了。
起始時(shí),把n/4保存在%ecx寄存器中,并把to和from的地址分別存入%edi和%esi (引用占位符)
然后重復(fù)調(diào)用movsl n/4次,接下來應(yīng)該還有(n mod 4)個(gè)字節(jié)尚未復(fù)制,這里用了一個(gè)比較巧妙的方法
movl %4, %%ecx 把n的值保存到%ecx
andl $3, %%ecx n與3做邏輯與,得到n mod 4
jz 1f 如果4 | n,跳過后面的復(fù)制
rep movsb 再?gòu)?fù)制(n mod 4)個(gè)字節(jié)
由于是按四個(gè)字節(jié)復(fù)制的,因此效率上memcpy肯定比strcpy高不少。