![]() |
[ASM] Lange Strings als Function - Wert zurückgeben
Hallo,
in der Dephi – Hilfe steht das man lange Strings im EAX – Register wieder zurückgibt. Zitat:
Delphi-Quellcode:
Mir ist jetzt nur nicht klar, wie ich den langen String in EAX bekomme (Also der Pointer), muss ich dafür in der Function selber den Speicherplatz reservieren, oder hat ein anderer Register die Anfangsadresse?
function strRueckgabe (s: PChar) : String;
ASM … Mach was mit s in ASM Functionsergebnis in EAX END; Bis bald Chemiker |
Re: [ASM] Lange Strings als Function - Wert zurückgeben
Schau dir einfach mal an, was der Delphi-Compiler normalerweise bastelt. Für dich dürfte die Funktion System.@NewAnsiString interessant sein (ich habe ziemlich lange gebraucht, bis ich begriffen habe, dass man die ganzen "Compiler-Magic-Funktion" aus System immer voll qualifizieren muss).
Dein PChar liegt ja am Anfang auch in eax. |
Re: [ASM] Lange Strings als Function - Wert zurückgeben
Dafür gibt es String-Funktionen. Schreib einfach mal irgendwas mit Strings in Delphi, mach nen Breakpoint rein und schau dir im CPU-Fenster an, wie der Compiler es macht.
|
Re: [ASM] Lange Strings als Function - Wert zurückgeben
jupp, schau mal in die System.pas, da gibt's die nötigen StringFunktionen, oder im CPU-Fenster nachsehn was Delphi gern aufruft.
wenn es unbedingt sein muß, dann kannst du auch einen kleinen Umweg gehn
Delphi-Quellcode:
Function strRueckgabe(S: PChar): String;
Var Temp: Array[0..1023] of Char; Begin ASM MOV EAX, &S MOV EDX, &Temp // in EAX steht nun der EingabeString-S // und in EDX stünde der Zeiger zu einem Puffer für den Rückgabewert END; Result := Temp; End; |
Re: [ASM] Lange Strings als Function - Wert zurückgeben
Hallo,
danke für die Antworten. Trotzdem verstehe ich immer noch nicht wie es funktioniert. Mal ein Beispiel für die Rückgabe eines integer – Wertes.
Delphi-Quellcode:
So das ist kein Problem.
function ASM_strLaenge(s: PChar): integer;
ASM PUSH EBX // EBX sichern MOV EDX, EAX // Adresse in EDX XOR EAX, EAX // EAX auf 0 setzen MOV EBX, EAX // EBX aof 0 setzen JMP @@Vergleich @@Weiter: INC EDX // Adresse um 1 Erhöhen INC EAX // Anzahl um 1 erhöhen @@Vergleich: MOV BL, [EDX] // Zeichen laden nach BL CMP byte ptr [EDX], $00 // Zeichen auf #0 testen JNZ @@Weiter // Wenn nicht String Ende dann weiter POP EBX // EBX vom Stack holen END; Aber, wenn ich diese zugegebener Weise nutzlose Funktion, in ASM schreiben möchte, wie sieht denn dann der Code aus.
Delphi-Quellcode:
function ASM_StringTest(s: String):String;
begin Result:= s; end; Bis bald Chemiker |
Re: [ASM] Lange Strings als Function - Wert zurückgeben
dein
Delphi-Quellcode:
sieht in ASM virtuell so aus
function ASM_StringTest(s: String):String;
begin Result:= s; end;
Delphi-Quellcode:
Function ASM_StringTest(S: String; In Result: String): String;
// das "In Result: String" wird sozusagen vom Compiler hinzugefügt, um // Stringvariablen und andere dynamische Arrays optimaler verwalten zu können. ASM // EAX = Refferenz auf S // EDX = Refferenz auf Result (vorinitialisiert) // EDX bearbeiten, z.B. S zuweisen MOV EAX, ...{EDX} // und zum Schluß die Refferenz in EAX zurückgeben End; Bei Varianten mit festen Speichern, wie in Beitrag #4, braucht man sich dagegen um Speicherresservierung garkeine Sorgen zu machen ... S als PChar interpretieren (bei 'nem reinem Lesezugriff ist das möglich), der Puffer braucht nicht verwaltet zu werden und um den Rest kümmert sich Delphi. |
Re: [ASM] Lange Strings als Function - Wert zurückgeben
Hallo,
habe die Rückgabe eines Strings in einer Function jetzt so gelöst. Kann einer sich den Code mal ansehen, ob er so ok ist. Das Umwandeln in Kleinbuchstabe vom String ist nur für Testzwecke um zu sehen ob das ganze Ordentlich funktioniert.
Delphi-Quellcode:
function ASM_StringTest(s: String): String;
var StrPChar: PChar; // String Adresse von s merken ASM PUSH EBX // EBX --> Stack MOV StrPChar, EAX //****************************************************************************** // String - Länge von s bestimmen // Parameter: EAX <-- Adresse von s //****************************************************************************** MOV EBX, EAX // Adresse s --> EBX XOR EAX, EAX // EAX:= 0 // Vorbreitung zu zählen JMP @@Vergleich @@Weiter1: INC EBX // EBX:= s[EBX] INC EAX // EAX:= EAX + 1 // Zähler um 1 erhöhen @@Vergleich: // Zeichen was an EBX in s steht vergleichen CMP byte ptr [EBX], $00 // if EBX <> #0 then // Weiter1; JNZ @@Weiter1 // endif //****************************************************************************** // In EAX ist die String - Länge von s // String - Länge ENDE //****************************************************************************** MOV EBX, EAX // s String- Länge --> EBX //****************************************************************************** // Vorbereitung um den Speicher für den Rückgabe - String vorzubereiten // Zustand der Reg.: EAX = String - Länge von s // EDX = Adresse vom Rückgabe - String // Für den Aufruf der Procedure: _LStrSetLength in der System-Unit müssen die // beiden Inhalte der Reg. getauscht werden. // procedure _LStrSetLength (Adresse, String-Länge) // _LStrSetLength (EAX, EDX) ( XCHG EDX, EAX // Adresse vom Rückgabe-String in EAX // Länge die Reserviert werden soll in EDX CALL System.@LStrSetLength // _LStrSetLength (EAX, EDX); // _LStrSetLength (Adresse, Länge) //****************************************************************************** // In EAX ist die Adresse vom Rückgabe - Sring //* **************************************************************************** // Prüfen ob der String ='' ist // if StrLaenge = 0 then exit; MOV ECX, EBX // ECX := StrLaenge; TEST ECX, ECX // Flags setzen JZ @@Schluss // Wenn die String - Länge = 0 dann ist //****************************************************************************** // Kopieren eines Strings der in KleinBuchstaben umgewandelt wird und in den // Rückgabe String kopiert wird. // nur für Testzwecke ob der Rückgabe - String richtig zurückgegeben wird. //****************************************************************************** PUSH EAX // Adresse vom Rückgabe - String --> Stack PUSH ESI // ESI --> Stack PUSH EDI // EDS --> Stack MOV ESI, StrPChar MOV EDI, [EAX] @@CopySchleife: LODSb CMP AL, 'A' JB @@Buchstabe CMP AL, 'Z' JA @@Buchstabe ADD AL, 32 @@Buchstabe: STOSb AND AL, AL JNZ @@CopySchleife POP EDI // Stack --> EDI POP ESI // Stack --> ESI POP EAX // Adresse Rückgabe String --> EAX @@Schluss: POP EBX // Stack --> EBX END; Bis bald Chemiker |
Re: [ASM] Lange Strings als Function - Wert zurückgeben
Delphi-Quellcode:
EAX zeigt auf @TAnsiStringInfo.Data
// EAX = Zeiger auf String
TEST EAX, EAX JZ @EmptyString // S = '' MOV EDX, DWOD PTR [EAX - 4] // EDX = StringLänge in Byte (ohne #0) und TAnsiStringInfo[S].ElementCount = Length(S)
Delphi-Quellcode:
und
TAnsiStringInfo = packed Record
RefCount: LongInt; ElementCount: LongInt; Data: packed Array[1..High(Integer) - SDynArrayInfo] of AnsiChar; End; ![]()
Delphi-Quellcode:
PChar_Length(EAX) = LStrLen(EAX)
[edit=Matze]Code auf Wunsch von himitsu angepasst. MfG, Matze[/edit] |
Re: [ASM] Lange Strings als Function - Wert zurückgeben
Hallo himitsu,
das ist ja eine sehr kurze Methode um die Länge von einem AnsiString zu ermitteln. Habe den Record zwar auch beim Analysieren von der System – Unit gesehen, aber nicht getraut zu Verwenden (wegen Seiteneffekte). Nur so wie Du den Code – Schnipsel geschrieben hast wird immer die Länge des Strings mit Null angezeigt.
Delphi-Quellcode:
Habe es etwas modifiziert:
XOR EAX, EAX // ergibt immer 0
Delphi-Quellcode:
Danke für Deinen Hinweis.
function ASM_StrLaengeKurz(s: String): integer;
ASM MOV EDX, EAX JZ @@EmptyString // S = '' MOV EAX, [EDX - 4] @@EmptyString: END; Bis bald Chemiker |
Re: [ASM] Lange Strings als Function - Wert zurückgeben
Dein bedingter Sprung scheint mir sehr gewagt. Mov setzt keine Flags, also ist das Zero-Flag nach dem Zufallsprinzip gesetzt.
Ich würde die Funktion folglich so schreiben:
Delphi-Quellcode:
function ASM_StrLaengeKurz(s: String): integer;
ASM TEST EAX, EAX JZ @@EmptyString // S = '' MOV EAX, [EAX - 4] @@EmptyString: END; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz