CopyMemory的源码困惑

Jekhn 2010-09-20 10:25:46
以下是D7 CopyMemory的源码,有两个问题不太明白,望高手解答
1.CMP EDI,ESI,当EDI>ESI(P1>P2)的时候会JMP到@@down,难后倒着执行复制?REP MOVS*这些指令的执行会关系到ESI,EDI谁大谁小?
2.在调试的时候发现都是执行上面的代码,不会JMP到@@down,调整定义P1,P2对应变量的位置也没用,是编译器做了优化吗?我是用下面的代码在D2010测试的。

procedure _CopyMemory(P1, P2: Pointer; Len: Integer); assembler;
asm
PUSH ESI
PUSH EDI
MOV EDI,EAX { destination address }
MOV ESI,EDX { source address }
MOV EAX,ECX
CMP EDI,ESI
JA @@down
JE @@exit
SAR ECX,2 { copy count DIV 4 dwords }
JS @@exit
REP MOVSD
MOV ECX,EAX
AND ECX,03H
REP MOVSB { copy count MOD 4 bytes }
JMP @@exit
@@down:
LEA ESI,[ESI+ECX-4] { point ESI to last dword of source }
LEA EDI,[EDI+ECX-4] { point EDI to last dword of dest }
SAR ECX,2 { copy count DIV 4 dwords }
JS @@exit
STD
REP MOVSD
MOV ECX,EAX
AND ECX,03H { copy count MOD 4 bytes }
ADD ESI,4-1 { point to last byte of rest }
ADD EDI,4-1
REP MOVSB
CLD
@@exit:
POP EDI
POP ESI
end;
...全文
168 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
iqyely 2010-09-20
  • 打赏
  • 举报
回复
来学习下
白耗子 2010-09-20
  • 打赏
  • 举报
回复
顶一个
Hexpate 2010-09-20
  • 打赏
  • 举报
回复
看一下如下实例, 当DI > SI的时候如果正向复制的话就会导致如下情况. 复制函数为了保证效率采用了CPU字长大小的方式进行COPY, 当你是32位的CPU一次拷贝4个字节是最有效率的.

初始
SI -> 1
DI-> 2
3
4
5
6
7
8

第一轮
1
1
2
SI-> 3
DI-> 4
6
7
8

第2轮
1
1
2
3
3
4
Si 6
Di 7
看到了吗, 这不是我们想要的结果, 这个时候只有反着进行copy才能达到我们想要的效果.
另外你说交换了位置也不会执行down我认为可能是你看错了, 再者可能是你的2个指针指向的是同一个位置
Jekhn 2010-09-20
  • 打赏
  • 举报
回复
谢谢Hexpate的回复,好详细,我没有想到复制和被复制的内存是可以重叠的,另外@@down里面确实会执行,我是搞错了,像下面在局部变量把定义的位置对调就会产生跳转,昨天搞得晕晕的没有测试出来。同样谢谢CaesarDM。
var
//arr2: array [1..10] of Byte;
arr1: array [1..10] of Byte;
arr2: array [1..10] of Byte;
begin
...
CopyMemory(@arr1,@arr2,10);
end;
CaesarDM 2010-09-20
  • 打赏
  • 举报
回复
倒着COPY是一个保护源数据不被破坏的处理
当然这是一个特例,只在复制的内存区域有交错的情况下发生

比如
var a :array[0..n] of Byte

CopyMemory(@a[10], @a[0],20);

在复制到第11个字节时,其实该内存已经变成了a[0]的内容。

所以,判断一下ESI EDI的大小,决定是正向还是反向Copy是非常有必要的。

至后面的REP MOVSD,REP MOVSB,只是在适用范围使用最快的运算来搬字节,每次按DWORD大小复制,当字节不足4字节时,按BYTE复制。

16,749

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧