你的问题:
var
p : PChar;
a : array[0..255] of Char;
s : String;
begin
s := p;
s := a;
end;
我想知道在s := a;背后Delphi作了些什么?=======================================================其实你调出CPU窗口一目了然。代码整理如下:var
a : array[0..255] of Char;
s : String;
begin
FillChar(a, 256, 0);
s := a;
end;Delphi背后调用了一个内建函数。从长数组转换为长字符串得这么一个函数。_LStrFromArray其实一样转化为PChar来操作。Unit1.pas.31: s := a;
00454712 8D45FC lea eax,[ebp-$04]
00454715 8D95FCFEFFFF lea edx,[ebp-$00000104]
0045471B B900010000 mov ecx,$00000100
00454720 E887FDFAFF call @LStrFromArray
00454725 33C0 xor eax,eax
00454727 5A pop edx
00454728 59 pop ecx
00454729 59 pop ecx
0045472A 648910 mov fs:[eax],edx
0045472D 6842474500 push $00454742
00454732 8D45FC lea eax,[ebp-$04]
00454735 E80AFBFAFF call @LStrClr
0045473A C3 ret
procedure _LStrFromArray(var Dest: AnsiString; Source: PAnsiChar; Length: Integer);
asm
PUSH EDI
PUSH EAX
PUSH ECX
MOV EDI,EDX
XOR EAX,EAX
REPNE SCASB
JNE @@1
NOT ECX
@@1: POP EAX
ADD ECX,EAX
POP EAX
POP EDI
JMP _LStrFromPCharLen
end;其实还是用的指针用了PChar。具体的查看system.pas内部的函数原型。procedure _LStrFromPCharLen(var Dest: AnsiString; Source: PAnsiChar; Length: Integer);
asm
{ -> EAX pointer to dest }
{ EDX source }
{ ECX length } PUSH EBX
PUSH ESI
PUSH EDI MOV EBX,EAX
MOV ESI,EDX
MOV EDI,ECX { allocate new string } MOV EAX,EDI CALL _NewAnsiString
MOV ECX,EDI
MOV EDI,EAX TEST ESI,ESI
JE @@noMove MOV EDX,EAX
MOV EAX,ESI
CALL Move { assign the result to dest }@@noMove:
MOV EAX,EBX
CALL _LStrClr
MOV [EBX],EDI POP EDI
POP ESI
POP EBX
end;
var
p : PChar;
a : array[0..255] of Char;
s : String;
begin
s := p;
s := a;
end;
我想知道在s := a;背后Delphi作了些什么?=======================================================其实你调出CPU窗口一目了然。代码整理如下:var
a : array[0..255] of Char;
s : String;
begin
FillChar(a, 256, 0);
s := a;
end;Delphi背后调用了一个内建函数。从长数组转换为长字符串得这么一个函数。_LStrFromArray其实一样转化为PChar来操作。Unit1.pas.31: s := a;
00454712 8D45FC lea eax,[ebp-$04]
00454715 8D95FCFEFFFF lea edx,[ebp-$00000104]
0045471B B900010000 mov ecx,$00000100
00454720 E887FDFAFF call @LStrFromArray
00454725 33C0 xor eax,eax
00454727 5A pop edx
00454728 59 pop ecx
00454729 59 pop ecx
0045472A 648910 mov fs:[eax],edx
0045472D 6842474500 push $00454742
00454732 8D45FC lea eax,[ebp-$04]
00454735 E80AFBFAFF call @LStrClr
0045473A C3 ret
procedure _LStrFromArray(var Dest: AnsiString; Source: PAnsiChar; Length: Integer);
asm
PUSH EDI
PUSH EAX
PUSH ECX
MOV EDI,EDX
XOR EAX,EAX
REPNE SCASB
JNE @@1
NOT ECX
@@1: POP EAX
ADD ECX,EAX
POP EAX
POP EDI
JMP _LStrFromPCharLen
end;其实还是用的指针用了PChar。具体的查看system.pas内部的函数原型。procedure _LStrFromPCharLen(var Dest: AnsiString; Source: PAnsiChar; Length: Integer);
asm
{ -> EAX pointer to dest }
{ EDX source }
{ ECX length } PUSH EBX
PUSH ESI
PUSH EDI MOV EBX,EAX
MOV ESI,EDX
MOV EDI,ECX { allocate new string } MOV EAX,EDI CALL _NewAnsiString
MOV ECX,EDI
MOV EDI,EAX TEST ESI,ESI
JE @@noMove MOV EDX,EAX
MOV EAX,ESI
CALL Move { assign the result to dest }@@noMove:
MOV EAX,EBX
CALL _LStrClr
MOV [EBX],EDI POP EDI
POP ESI
POP EBX
end;
http://expert.csdn.net/Expert/topic/2940/2940590.xml?temp=.8431665
别客气!