Frage

Ich versuche, Inline-Assembly-Programmierung in Delphi zu lernen, und habe dieses Ziel gefunden Dieser Artikel sehr hilfreich.

Jetzt möchte ich eine Assembly-Funktion schreiben, die eine lange Zeichenfolge zurückgibt, insbesondere eine AnsiString (der Einfachheit halber).ich habe geschrieben

function myfunc: AnsiString;
asm
  // eax = @result
  mov edx, 3
  mov ecx, 1252
  call System.@LStrSetLength
  mov [eax + 0], ord('A')
  mov [eax + 1], ord('B')
  mov [eax + 2], ord('C')
end;

Erläuterung:

Eine Funktion, die eine Zeichenfolge zurückgibt, ist unsichtbar var result: AnsiString (in diesem Fall) Parameter, also am Anfang der Funktion eax sollte die Adresse der resultierenden Zeichenfolge enthalten.Ich habe dann eingestellt edx Und ecx bis 3 bzw. 1252 und rufen Sie dann an System._LStrSetLength.Tatsächlich tue ich das

  _LStrSetLength(@result, 3, 1252)

Dabei ist 3 die neue Länge der Zeichenfolge (in Zeichen = Bytes) und 1252 der Standard Windows-1252 Codepage.

Dann weiß ich das eax Ist die Adresse des ersten Zeichens der Zeichenfolge, ich habe die Zeichenfolge einfach auf „ABC“ gesetzt.Aber es funktioniert nicht – es gibt mir unsinnige Daten oder EAccessViolation.Was ist das Problem?

Aktualisieren

Jetzt haben wir zwei scheinbar funktionierende Implementierungen von myfunc, einer beschäftigt NewAnsiString und einer beschäftigt LStrSetLength.Ich frage mich, ob beide korrekt sind, in dem Sinne, dass sie Delphis interne Verarbeitung von Zeichenfolgen (Referenzzählung, automatisches Freigeben usw.) nicht durcheinander bringen.

War es hilfreich?

Lösung

Sie müssen Folgendes verwenden:

function myfunc: AnsiString;
asm
  push eax // save @result
  call system.@LStrClr
  mov    eax,3                 {Length}
{$ifdef UNICODE}
  mov    edx,1252 // code page for Delphi 2009/2010
{$endif}
  call   system.@NewAnsiString
  pop edx
  mov [edx],eax
  mov [eax],$303132
end;

Es wird eine Zeichenfolge „210“ zurückgegeben ...

Und es ist immer eine gute Idee, einen {$ifdef UNICODE}-Block einzufügen, damit Ihr Code mit Delphi-Versionen vor 2009 kompatibel ist.

Andere Tipps

Mit der hervorragenden Hilfe von A. Bouchez gelang es mir, meinen eigenen Code zu korrigieren LStrSetLength:

function myfunc: AnsiString;
asm

  push eax

  // eax = @result
  mov edx, 3
  mov ecx, 1252
  call System.@LStrSetLength

  pop eax

  mov ecx, [eax]

  mov [ecx], 'A'
  mov [ecx] + 1, 'B'
  mov [ecx] + 2, 'C'

end;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top