Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   ASM Pointer Dereferenzierung (https://www.delphipraxis.net/178509-asm-pointer-dereferenzierung.html)

KFAF 11. Jan 2014 19:04

ASM Pointer Dereferenzierung
 
Hallo Delphi Praxis!

Ich habe folgendes Problem:

Delphi-Quellcode:
procedure Foo(A : Pointer); assembler;
var
  Test : Pointer;
asm
  MOV Test, A

  .
  .
  .

  MOV EAX, [Test]
end;
Obwohl der Wert von Test korrekt ist, liefert MOV in EAX lediglich den Wert des Zeigers. Da Test gleichbedeutend mit [ESP - 4] ist, dachte ich , man müsste [[TEST]] schreiben. Das hat aber genau die selbe Wirkung.

Es funktioniert allerdings, wenn ich zuerst Test in ein Register lade, und anschließend statt [Test] [Register-Name] einsetzte. Ich habe aber kein Register mehr frei, zumindest nicht, ohne noch x-tausend stack Operationen an allen Stellen einzufügen.

Wäre wirklich toll, wenn mich mal jemand darüber aufklären könnte!

Mit freundlichen Grüßen zum neuen Jahr
KFAFSP

Namenloser 11. Jan 2014 19:37

AW: ASM Pointer Dereferenzierung
 
Kannst du vielleicht mal mit Pascal-Code beschreiben, was du machen willst? Mir ist es nicht ganz klar.

Du kannst auf jeden Fall zwei mal hintereinander dereferenzieren, unter Benutzung desselben Registers:
Delphi-Quellcode:
MOV EAX, [Test]
MOV EAX, [EAX]
Ich weiß aber nicht, ob das das ist, was du machen willst.

KFAF 11. Jan 2014 20:37

AW: ASM Pointer Dereferenzierung
 
Ok, nochmal in Worten.

Ich möchte einen Zeiger-Parameter auf das erste Element eines Arrays, welcher mir beim Aufruf der Funktion übergeben wird, in einer lokalen Variable innerhalb dieser Funktion aufbewahren, da das EAX Register welches diese Variable beim Einsprung enthält anderweitig verwendet werden soll. Zu einem späteren Zeitpunkt der Ausführung im selben Aufruf möchte ich nun aber den gespeicherten Zeiger dereferenzieren, also auf das Element des Arrays zugreifen, auf das er zeigt. Pascal :

Delphi-Quellcode:
function Foo(A : PByteArray) : Byte;
var
  pTemp : PByteArray;
begin
  pTemp := A;

  .
  .
  .

  Result := pTemp^[0];
end;
Das ist nur ein Beispiel, ich will nicht wirklich den Rückgabewert der Funktion setzten, und es muss auch nicht das 0-te Element sein.

Namenloser 11. Jan 2014 20:55

AW: ASM Pointer Dereferenzierung
 
Zitat:

Zitat von KFAF (Beitrag 1243211)
Ich möchte einen Zeiger-Parameter auf das erste Element eines Arrays, welcher mir beim Aufruf der Funktion übergeben wird, in einer lokalen Variable innerhalb dieser Funktion aufbewahren, da das EAX Register welches diese Variable beim Einsprung enthält anderweitig verwendet werden soll.

Ok, also das machst du ja.

Zitat:

Zitat von KFAF (Beitrag 1243211)
Zu einem späteren Zeitpunkt der Ausführung im selben Aufruf möchte ich nun aber den gespeicherten Zeiger dereferenzieren, also auf das Element des Arrays zugreifen, auf das er zeigt.

Du musst zuerst den Zeiger in ein Register laden. Anders geht es nicht. Es gibt soweit ich weiß keinen Befehl, um eine zweifache Dereferenzierung in einem Schritt durchzuführen.

Wenn du nicht genug Register hast, dann musst du dir was einfallen lassen... Assembler-Programmierung ist leider umständlich.

Welche Register nutzt du denn schon? Alle? Oder nur die "flüchtigen" (EAX, EDX, ECX)? Dann könntest du noch was rausholen, indem du weitere Register (EDI, ESI) mit einbeziehst. Diese musst du beim Eintritt der Routine mit PUSH sichern und am Ende mit POP wiederherstellen. Ansonsten musst du wohl jonglieren...

Edit: Oder vielleicht reichen dir an manchen Stellen ja auch "halbe" Register (z.B. Schleifen-Zähl-Variablen.) – also die alten 16-Bit-Register, AL, AX und Co. Vielleicht kannst du damit irgendwo noch ein Register sparen.

KFAF 11. Jan 2014 21:03

AW: ASM Pointer Dereferenzierung
 
Danke nochmal!

Ich habe mal was über Addressierungsoptionen gelesen, und dachte Indirect-Indirect wäre möglich. Aber die Praxis beweist das Gegenteil!

Du hattest aber recht, am besten (einfachsten) geht es mit:

Delphi-Quellcode:
MOV EAX, Test ( = MOV EAX, [ESP - 4])
MOV EAX, [EAX]
Darauf bin ich garnicht gekommen, und so brauche ich auch kein zweites Register. Sind auch bloß zwei Kommandos, also ist es ja ok. Gut, dass ich noch so schnell eine Antwort bekommen habe! Der Rest des Quelltextes funktioniert auch, obwohl ich ja vorher noch garkeine Gelegenheit hatte, ihn zu testen.

Nur wenn es interessiert : es ist eine SHA-1 Implementation in ASM, Profiling sagt sie ist ca. 230% schneller. Lohnt sich wirklich!

himitsu 11. Jan 2014 21:08

AW: ASM Pointer Dereferenzierung
 
du kannst die Variable auch selber auf dem Stack ablegen und dann direkt draufzugreifen.

Namenloser 11. Jan 2014 21:09

AW: ASM Pointer Dereferenzierung
 
Zitat:

Zitat von himitsu (Beitrag 1243216)
du kannst die Variable auch selber auf dem Stack ablegen und dann direkt draufzugreifen.

Dann hat man allerdings trotzdem immer noch dasselbe Problem.

Aber freut mich, dass ich helfen konnte :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz