首页
社区
课程
招聘
memcpy应该怎样写,同时庆祝新版开张
发表于: 2005-6-1 16:38 11927

memcpy应该怎样写,同时庆祝新版开张

2005-6-1 16:38
11927
如果:
char buf[512];
memset(buf,0,sizeof(buf));
buf[0]='k';
memcpy(&buf[1],buf,100);
结果buf中是什么?

如果我这样实现:
void memcpy(char *to,char * from,int len)
{
     for(int i=0;i<len;i++)
     {
        to[i]=from[i];
      }
}
结果又怎样。

你以为memcpy实现哪种结果更合理?

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (13)
雪    币: 343
活跃值: (611)
能力值: ( LV9,RANK:810 )
在线值:
发帖
回帖
粉丝
2
你上面那个在VC6中输出的结果是:
buf[0] = 'k';
buf[1] =  'k';
其余为0。

下面你给出的实现方法我个人认为不合理。VC中的memcpy的实现要复杂的多。我想是有道理的。如果源和目标空间重合的话。你的实现可能会有一部分数据丢失。
2005-6-1 17:04
0
雪    币: 519
活跃值: (1223)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
3
可以看一下VC6目录下\crt\src\intel\memcpy.asm
里面是memcpy的汇编实现,它是专门处理了overlap的情况
最好还是用写好的库.
2005-6-1 20:12
0
雪    币: 2319
活跃值: (565)
能力值: (RANK:300 )
在线值:
发帖
回帖
粉丝
4
最初由 hangj 发布
....
你以为memcpy实现哪种结果更合理?
........


如果以 C 语言的角度来看,根据 ANSI 标准,这种 overlap 的 memcpy 是 undefined behavior,
所有结果都不可以说是合理的

OS 可以合法地用任何方式去处理这种情况,在任何 OS 或任何版本上,实践手法可
以不同。包括,先把 src 复制后写到 dst,或是先把 scr 清空,但也可能使机器当机,
或是每一次都随机地执行任何方式。如果说Microsoft windows,在每一个版本上
Microsoft 都可以自由地使用任何方式,但都是合符标准。

普遍的建议是,不要做这一种 undefined behavior 的动作,如果需要把内存移动,
应该使用 memmove

(reference : ISO/IEC 9899:1999  7.21.2.1 )
2005-6-2 08:09
0
雪    币: 229
活跃值: (168)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
5
原来如此,多谢各位了
2005-6-2 09:36
0
雪    币: 216
活跃值: (370)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
6
注意memcpy的类型:
void * memcpy(void * to,void * from,size_t len);
原型不能错。
特别是返回值是void*,返回to的值。
不能搞错。
2005-6-3 10:36
0
雪    币: 288
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
同意四楼的,如果有overlap时,要使用memmove。我自己写个试试:

void *memcpy(void *to, const void *from, unsigned int len)
{
        char *dest = (char *)to;
        char *source = (char *)from;
        assert(to);
        assert(from);

        while(len--)
                *dest++= *source++;
        return to;
}

btw:to robo
可以看一下VC6目录下\crt\src\intel\memcpy.asm
里面是memcpy的汇编实现,它是专门处理了overlap的情况
最好还是用写好的库
我安装的vc没有这些东东,能否发一份给我:hejiwen2001@sohu.com
谢谢了!
2005-6-3 11:19
0
雪    币: 519
活跃值: (1223)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
8
同意riijj 下面是VC6里面memcpy.asm文件前面的算法注释,大家可以看得很明白了,不过在VC6里这两个函数的处理好像是相同的...

;***
;memcpy.asm - contains memcpy and memmove routines
;
;       Copyright (c) 1986-1997, Microsoft Corporation. All right reserved.
;
;Purpose:
;       memcpy() copies a source memory buffer to a destination buffer.
;       Overlapping buffers are not treated specially, so propogation may occur.
;       memmove() copies a source memory buffer to a destination buffer.
;       Overlapping buffers are treated specially, to avoid propogation.
;
;*******************************************************************************
;***
;memcpy - Copy source buffer to destination buffer
;
;Purpose:
;       memcpy() copies a source memory buffer to a destination memory buffer.
;       This routine does NOT recognize overlapping buffers, and thus can lead
;       to propogation.
;       For cases where propogation must be avoided, memmove() must be used.
;
;       Algorithm:
;
;       void * memcpy(void * dst, void * src, size_t count)
;       {
;               void * ret = dst;
;
;               /*
;                * copy from lower addresses to higher addresses
;                */
;               while (count--)
;                       *dst++ = *src++;
;
;               return(ret);
;       }
;
;memmove - Copy source buffer to destination buffer
;
;Purpose:
;       memmove() copies a source memory buffer to a destination memory buffer.
;       This routine recognize overlapping buffers to avoid propogation.
;       For cases where propogation is not a problem, memcpy() can be used.
;
;   Algorithm:
;
;       void * memmove(void * dst, void * src, size_t count)
;       {
;               void * ret = dst;
;
;               if (dst <= src || dst >= (src + count)) {
;                       /*
;                        * Non-Overlapping Buffers
;                        * copy from lower addresses to higher addresses
;                        */
;                       while (count--)
;                               *dst++ = *src++;
;                       }
;               else {
;                       /*
;                        * Overlapping Buffers
;                        * copy from higher addresses to lower addresses
;                        */
;                       dst += count - 1;
;                       src += count - 1;
;
;                       while (count--)
;                               *dst-- = *src--;
;                       }
;
;               return(ret);
;       }


btw :to hejiwen,邮件已发出
2005-6-3 12:01
0
雪    币: 2319
活跃值: (565)
能力值: (RANK:300 )
在线值:
发帖
回帖
粉丝
9
我觉得,如果自己以 C 语言写,是不能达到汇编 memcpy 的速度,最主要的原因是汇编使用了  “rep movsd “ ,这个 rep 使 CPU 快速地复制 DWORD  
2005-6-3 13:37
0
雪    币: 288
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
10
支持!
我用rep movsb写个试试,全当练习,请高手指点:

_MemCpy proc _to, _from, _len
        .if _to == NULL || _from == NULL
                mov   eax,NULL
                ret
        .endif

        mov   ecx, _len
        mov   esi, _from
        mov   edi, _to
        rep   movsb
        mov   eax, _to
        ret
_MemCpy endp
2005-6-3 16:03
0
雪    币: 288
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
11
目的:练习一下类型转换!
;       Algorithm:
;
;       void * memcpy(void * dst, void * src, size_t count)
;       {
;               void * ret = dst;
;
;               /*
;                * copy from lower addresses to higher addresses
;                */
;               while (count--)
;                       *dst++ = *src++;
;
;               return(ret);
;       }

改为
void * memcpy(void * dst, void * src, size_t count)      
{                                                         
         void * ret = dst;
                                                           
         /*                                                
          * copy from lower addresses to higher addresses  
          */                                               
         while (count--)                                    
         {
             *(char*)dst = *(char*)src;                    
             dst = (char*)dst+1;
             src = (char*)src+1;
         }
                                                           
         return(ret);                                      
}
2005-6-6 17:01
0
雪    币: 216
活跃值: (370)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
12
最初由 hejiwen 发布
支持!
我用rep movsb写个试试,全当练习,请高手指点:

_MemCpy proc _to, _from, _len
.if _to == NULL || _from == NULL
........

标准的memcpy不检查参数的值。
如果传NULL就一定死掉,那是你的事,不是memcpy的事。
第二,你这个如果数据没有对齐的话慢死了。
vc的asm为什么在movsd之前加了那么多废话?
就是为了数据对齐先。
2005-6-6 17:54
0
雪    币: 2319
活跃值: (565)
能力值: (RANK:300 )
在线值:
发帖
回帖
粉丝
13
所以自己不用写,用 vc 的 memcpy 便好了
2005-6-6 18:09
0
雪    币: 288
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
14
我只知道在c语言中的结构体中,成员变量数据对不齐,会出现取成员变量出错,能讲一讲汇编中数据对齐与指令的关系吗?谢谢!
2005-6-7 10:23
0
游客
登录 | 注册 方可回帖
返回
//