Delphi System单元-Move - 移动内存数据,不分类型 untyped

Delphi System单元 - Move - 移动内存数据,不分类型 untyped    {解释权归本博客,如有错,请指出,谢谢}

单元:System

Move 原型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure  Move( const Source; var Dest; count : Integer );  
var
  S, D: PChar;
  I: Integer;
begin
  S := PChar(@Source);  //指针地址
  D := PChar(@Dest);  //
  if S = D then Exit;
  if Cardinal(D) > Cardinal(S) then
    for I := count-1 downto 0 do
      D[I] := S[I]
  else
    for I := 0 to count-1 do
      D[I] := S[I];
end;

还有一段汇编的原型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
procedure       Move( const Source; var Dest; count : Integer );
asm
{     ->EAX     Pointer to source       }
{       EDX     Pointer to destination  }
{       ECX     Count                   }
 
        PUSH    ESI
        PUSH    EDI
 
        MOV     ESI,EAX
        MOV     EDI,EDX
 
        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;

以上可以看出Move 的功能是很强大的,也可以直接用汇编来编译, 简单的可以理解为:Move 移动内存数据,不分类型   {解释权归本博客,如有错,请指出,谢谢}

 

Delphi 使用示例1:

// 本例将字符从Char数组移到整数中。将整数显示为十六进制时,可以看到“W”(0x57)存储在整数的最低有效字节中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var
  A: array[1..4] of Char;
  B: Integer;
 
procedure DisplayAB;
begin
  Form1.ListBox1.Items[0] := A[1];
  Form1.ListBox1.Items[1] := A[2];
  Form1.ListBox1.Items[2] := A[3];
  Form1.ListBox1.Items[3] := A[4];
  Form1.Edit1.Text := IntToHex(B, 1);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  Move(A, B, SizeOf(B));  { SizeOf = safety! }
  DisplayAB;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
var
  I : Integer;
begin
  A[1] := 'W';
  A[2] := 'H';
  A[3] := 'A';
  A[4] := 'T';
  B := 5;
  DisplayAB;
end;

注意:此方法有一个非类型化参数,这可能导致内存损坏。若要避免此问题,请对方法的最后一个参数使用SizeOf。

Source、Dest 都没有指明类型,而是 untyped parameter

 

Delphi 使用示例2:

1
2
3
4
5
6
7
8
var
Source,Dest: string;
begin
  Source := '123456789';
  Dest   := '---------';
  Move(Source[5], Dest[3], 4);      //将Source按字节拷贝到Dest。Count为要拷贝的字节数。
  ShowMessage(Dest); {--5678---}
end;

  

 

 

创建时间:2020.06.23  更新时间:

 

posted on   滔Roy  阅读(718)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报

导航

点击右上角即可分享
微信分享提示