posts - 403, comments - 310, trackbacks - 0, articles - 7
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          日歷

          <2007年10月>
          30123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          相冊

          搜索

          •  

          積分與排名

          • 積分 - 337540
          • 排名 - 166

          最新評論

          memcpy函數代碼分析

          Posted on 2007-10-19 23:56 ZelluX 閱讀(9392) 評論(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 菜鳥
          分析一下以上代碼
          51La
          主站蜘蛛池模板: 辉县市| 商城县| 兴海县| 怀柔区| 长白| 哈密市| 栖霞市| 和林格尔县| 延川县| 东城区| 白山市| 苏尼特左旗| 丹巴县| 香格里拉县| 运城市| 喀喇沁旗| 松阳县| 陵川县| 青铜峡市| 皋兰县| 云梦县| 漠河县| 临泽县| 永顺县| 安图县| 马公市| 宜昌市| 涞源县| 新乡县| 稷山县| 长沙县| 南京市| 县级市| 交城县| 武汉市| 白沙| 英超| 彰武县| 洪洞县| 济南市| 临颍县|