能力值:
( LV9,RANK:810 )
2 楼
你上面那个在VC6中输出的结果是:
buf[0] = 'k';
buf[1] = 'k';
其余为0。
下面你给出的实现方法我个人认为不合理。VC中的memcpy的实现要复杂的多。我想是有道理的。如果源和目标空间重合的话。你的实现可能会有一部分数据丢失。
能力值:
( LV12,RANK:650 )
3 楼
可以看一下VC6目录下\crt\src\intel\memcpy.asm
里面是memcpy的汇编实现,它是专门处理了overlap的情况
最好还是用写好的库.
能力值:
(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 )
能力值:
( LV8,RANK:130 )
5 楼
原来如此,多谢各位了
能力值:
( LV7,RANK:100 )
6 楼
注意memcpy的类型:
void * memcpy(void * to,void * from,size_t len);
原型不能错。
特别是返回值是void*,返回to的值。
不能搞错。
能力值:
( 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
谢谢了!
能力值:
( 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,邮件已发出
能力值:
(RANK:300 )
9 楼
我觉得,如果自己以 C 语言写,是不能达到汇编 memcpy 的速度,最主要的原因是汇编使用了 “rep movsd “ ,这个 rep 使 CPU 快速地复制 DWORD
能力值:
( 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
能力值:
( 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);
}
能力值:
( LV7,RANK:100 )
12 楼
最初由 hejiwen 发布 支持! 我用rep movsb写个试试,全当练习,请高手指点: _MemCpy proc _to, _from, _len .if _to == NULL || _from == NULL ........
标准的memcpy不检查参数的值。
如果传NULL就一定死掉,那是你的事,不是memcpy的事。
第二,你这个如果数据没有对齐的话慢死了。
vc的asm为什么在movsd之前加了那么多废话?
就是为了数据对齐先。
能力值:
(RANK:300 )
13 楼
所以自己不用写,用 vc 的 memcpy 便好了
能力值:
( LV6,RANK:90 )
14 楼
我只知道在c语言中的结构体中,成员变量数据对不齐,会出现取成员变量出错,能讲一讲汇编中数据对齐与指令的关系吗?谢谢!