Code- oder DatenSegment ist erstmal egal, wird doch eh nur in den Speicher reingemappt?
Also belegt nur virtuellen und keinen reellen
RAM.
Und das EXE-Packer/-Crypter das Speichermanagement zerstören sollte bekannt sein. (also ignoriert)
Delphi-Quellcode:
Const
S1 = '123';
i1 = 123;
S2: String = '234';
i2: Integer = 234;
Procedure P1;
Const
S3 = '345';
i3 = 345;
S4: String = '456';
i4: Integer = 456;
Begin
Form1.Memo1.Lines.Add(Format('S3 $%.8x $%.8x = "%s"', [0, Integer(@S3[1]), S3]));
Form1.Memo1.Lines.Add(Format('i3 $%.8x = %d', [0, i3]));
Form1.Memo1.Lines.Add(Format('S4 $%.8x $%.8x = "%s"', [Integer(@S4), Integer(S4), S4]));
Form1.Memo1.Lines.Add(Format('i4 $%.8x = %d', [Integer(@i4), i4]));
End;
Procedure P2;
Const
i5 = 567;
Begin
Form1.Memo1.Lines.Add(Format('i5 $%.8x = %d', [0, i5]));
End;
Procedure TForm1.FormCreate(Sender: TObject);
Var
S6: String;
i6: Integer;
Begin
S6 := '678';
i6 := 678;
Memo1.Lines.Clear;
Memo1.Lines.Add(Format('S1 $%.8x $%.8x = "%s"', [0, Integer(@S1[1]), S1]));
Memo1.Lines.Add(Format('i1 $%.8x = %d', [0, i1]));
Memo1.Lines.Add(Format('S2 $%.8x $%.8x = "%s"', [Integer(@S2), Integer(S2), S2]));
Memo1.Lines.Add(Format('i2 $%.8x = %d', [Integer(@i2), i2]));
Memo1.Lines.Add(Format('P1 $%.8x', [Integer(@P1)]));
P1;
Memo1.Lines.Add(Format('P2 $%.8x', [Integer(@P2)]));
P2;
Memo1.Lines.Add(Format('S6 $%.8x $%.8x = "%s"', [Integer(@S6), Integer(S6), S6]));
Memo1.Lines.Add(Format('i6 $%.8x = %d', [Integer(@i6), i6]));
UniqueString(S6);
Memo1.Lines.Add('');
Memo1.Lines.Add(Format('S6 $%.8x $%.8x = "%s"', [Integer(@S6), Integer(S6), S6]));
Memo1.Lines.Add('');
Memo1.Lines.Add('');
Memo1.Lines.Add('$00000000 = inline Konstante ... wird direkt im Code ersetzt');
End;
Raus kommt dann etwa sowas:
- Erstes = Position der Variable/Konstante
- Zweites = Position der Stringdaten (des Inhaltes)
Zitat:
S1 $00000000 $0044F334 = "123"
i1 $00000000 = 123
S2 $00450D9C $0044EC68 = "234"
i2 $00450DA0 = 234
P1 $0044EC78
S3 $00000000 $0044EE0C = "345"
i3 $00000000 = 345
S4 $00450DA4 $0044EC74 = "456"
i4 $00450DA8 = 456
P2 $0044EEA8
i5 $00000000 = 567
S6 $0012FE18 $0044F328 = "678"
i6 $0012FE14 = 678
S6 $0012FE18 $008D2290 = "678"
$00000000 = inline Konstante ... wird direkt im Code ersetzt
Pascal-Definition der delphiinternen Typen (Auszug):
Delphi-Quellcode:
Type TShortStringInfo =
packed Record // PShortStringInfo := @Var
Len: Byte;
Chars:
packed Array[1..255
{1..Len}]
of Char;
End;
PShortStringInfo = ^TShortStringInfo;
(*************************************************************************** )
( )
( P___Info := Pointer(var) - SDynArrayInfo )
( Pointer(var) := T___Info.___Addr )
( )
( A String/AnsiString is an packed Array of Char and just the same as near the )
( packed Array of Char an additional #0 is attached also there still behind. )
( (for the PChar compatibility) )
( )
( The WideString and the packed Array of WideChar are also identical )
( and there #0#0 hide themselves behind that. )
( )
(*************************************************************************** )
( )
( T___Info / P___Info: )
( ******************** )
( )
( Pointer(var) = nil > nil {in EXE} > nil {in RAM} )
( )
( RefCount - = -1 > 0 )
( ElementCount - > 0, = Length(var) > 0, = Length(var) )
( Data - = var = var )
( )
(****************************************************************************)
Const SDynArrayInfo = 2 * SizeOf(LongInt);
Type TDynArrayInfo =
packed Record
RefCount: LongInt;
ElementCount: LongInt;
Data:
packed Array[0..High(Integer) - SDynArrayInfo - 1]
of Byte;
End;
TAnsiStringInfo =
packed Record
RefCount: LongInt;
ElementCount: LongInt;
Data:
packed Array[1..High(Integer) - SDynArrayInfo]
of AnsiChar;
End;
TWideStringInfo =
packed Record
RefCount: LongInt;
ElementCount: LongInt;
Data:
packed Array[1..(High(Integer) - SDynArrayInfo)
div 2]
of WideChar;
End;
Aber nochmal zum Thema: 4 Byte pro Leer-String und diese müssen nicht im
RAM liegen.