Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2295080
  • 博文数量: 218
  • 博客积分: 5767
  • 博客等级: 大校
  • 技术积分: 5883
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-01 14:44
文章存档

2012年(53)

2011年(131)

2009年(1)

2008年(33)

分类: C/C++

2008-09-14 16:09:40

memcpy函数代码分析

memcpy调用了__memcpy函数执行内存的复制(__memcpy3d就先不管了),下面是这个这两个函数的代码


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/4保存在%ecx寄存器中,并把to和from的地址分别存入%edi和%esi (引用占位符)
然后重复调用movsl n/4次,接下来应该还有(n mod 4)个字节尚未复制,这里用了一个比较巧妙的方法
movl %4, %%ecx    把n的值保存到%ecx
andl $3, %%ecx    n与3做逻辑与,得到n mod 4
jz 1f             如果4 | n,跳过后面的复制
rep movsb         再复制(n mod 4)个字节

由于是按四个字节复制的,因此效率上memcpy肯定比strcpy高不少。
 
阅读(2812) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~