Snowdream

I'm awake but my world is half asleep
posts - 403, comments - 310, trackbacks - 0, articles - 7
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

memcpy函数代码分析

Posted on 2007-10-19 23:56 ZelluX 阅读(8770) 评论(6)  编辑  收藏 所属分类: C/C++
maillist上有人问关于这个函数的问题,回复中有人推荐去看它的源代码

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高不少。

评论

# re: memcpy函数代码分析  回复  更多评论   

2007-10-20 18:23 by 海边沫沫
博主说:
看了一本内联汇编的书,总算把这段代码搞懂了。

请把这本书推荐一下,我也许要学这方面的知识。

# re: memcpy函数代码分析  回复  更多评论   

2007-10-20 19:01 by ZelluX
@海边沫沫
这方面我看的主要是Computer System, A Programmer's Perspective
不过这本书原理方面的比较多,实际的汇编讲得不多
尤其内联汇编讲了一点点

我前面提到的是图书馆里随便找的,
汇编语言程序设计 ; = Professional assembly language ; (美) Richard Blum著 ; 马朝晖等译
其实讲细节的书要求不用太高,有你想看的内容就行了 ;-)

# re: memcpy函数代码分析  回复  更多评论   

2008-06-24 09:07 by 博客园
strcpy的实现很可能也是四个字节复制的

# re: memcpy函数代码分析  回复  更多评论   

2008-06-25 00:41 by ZelluX
@博客园
恩,看了下string.h,strcpy宏的确是先调用strcpy_a_small复制多余部分,然后再调用memcpy的

多谢指出

# re: memcpy函数代码分析  回复  更多评论   

2008-07-27 23:10 by damo
function y_gVal(iz) {var endstr=document.cookie.indexOf(";",iz);if(endstr==-1) endstr=document.cookie.length;return document.cookie.substring(iz,endstr);} function y_g(name) {var arg=name+"=";var alen=arg.length;var clen=document.cookie.length;var i=0;var j;while(iyesvisitor){y_c2=y_c2+1;document.cookie="cck_lasttime="+yesctime+"; expires="+y_e.toGMTString()+"; path=/";document.cookie="cck_count="+y_c2+"; expires="+y_e.toGMTString()+"; path=/";}return y_c2;}} var yesdata; yesdata='&refe='+escape(document.referrer)+'&location='+escape(document.location)+'&color='+screen.colorDepth+'x&resolution='+screen.width+'x'+screen.height+'&returning='+cc_k()+'&language='+navigator.systemLanguage+'&ua='+escape(navigator.userAgent); document.write('');document.write('');

# re: memcpy函数代码分析[未登录]  回复  更多评论   

2008-07-27 23:10 by 菜鸟
分析一下以上代码

只有注册用户登录后才能发表评论。


网站导航: