Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Objektfelder mit Inline Assembler benutzen (https://www.delphipraxis.net/766-objektfelder-mit-inline-assembler-benutzen.html)

Christian Seehase 3. Sep 2002 21:46


Objektfelder mit Inline Assembler benutzen
 
Moin Zusammen,

wie der Titel schon verrät, habe ich ein Objekt, dass Felder enthält, die ich mit Assembler benutzen will.
Bei diesen Feldern handelt es sich um Bufferpointer.

Das Auslesen des aktuellen Wertes gelingt mit

Code:
mov EDI,self.FpWork
auch problemlos, nur:

Wie bekomme ich anschliessend den veränderten Wert wieder in das Feld hinein?

Code:
mov self.FpWork,EDI
mov [self].FpWork,EDI
mov [self.FpWork],EDI
habe ich dazu schon probiert, allerdings mit dem kleinen Nachteil, dass sich in FpWork nach verlassen der Routine wieder der Eingangswert befindet (in jedem der drei Fälle)
Mit F7/F8 habe konnte ich schon feststellen, dass dieser Wert aber doch etwas anders sein müsste.

Christian Seehase 4. Sep 2002 11:10

Moin Zusammen,

jetzt bekomme ich allerdings Verständnisprobleme:

Zu Testzwecken habe ich mir einfach mal eine kleine Testmethode gebaut, die nichts weiter macht, als einen Pointer hochzuzählen.

Code:
asm
  push ESI
  mov ESI,self.FpTest
  inc ESI
  mov self.FpTest,ESI
  pop ESI
end;
Hier funktioniert das Setzen des Feldes problemlos.
Der Wert wird erhöht (was ja eigentlich auch so sein sollte).

In der Routine, in der es nicht funktioniert, stimmt der Wert im Feld, auch noch, wenn die gesicherten Register wieder zurückgeholt werden, erst nach verlassen der Methode nicht mehr :shock:

jbg 4. Sep 2002 14:14

Auf Self sollte man in asm-Blöcken nicht direkt zugreifen. Der Zeiger Self sollte vorher in ein Register übertragen werden, über dass dann der Zugriff auf die Fehler erfolgt.
Code:
[b]asm[/b]
  push eax
  push edx

  [u]mov eax, Self[/u]
  mov edx, TForm1([eax]).FTest
  inc edx
  mov TForm1([eax]).FTest, edx

  pop edx
  pop eax
[b]end;[/b]
Das ist im Beispie Self in das eax Register lade hab ich aus der OnlineHilfe zum Aufruf von dynamischen und virtuellen Methoden mittels Inline Assembler.

Christian Seehase 4. Sep 2002 14:25

Moin jbg,

erstmal Danke für die Info.
Die Hilfe welcher Delphi Version meinst Du? In der 5er kann ich nichts entsprechendes Entdecken.

Die Variante self erst in ein anderes Register zu laden und dann mit diesem Wert weiter hatte ich ursprünglich auch benutzt, war dann allerdings, da es vom Ergebnis her keinen Unterschied machte wieder davon abgekommen. :?
Mit ein bisschen Glück funktionierts dann ja damit stabil.

jbg 4. Sep 2002 14:54

OnlineHilfe von Delphi 6 (bei 5 steht es nicht drinnen): Assembler directives
Im Index auf "assembler statements"/"Assembler Anweisungen" gehen und dreimal den den Button ">>" drücken. (Text steht weit unten)

Code:
[b]asm[/b]
  [i][u]// Instance pointer needs to be in EAX[/u][/i]
  MOV    EAX, e
  [i]// Retrieve VMT table entry[/i]
  MOV    EDX, [EAX]
  [i]// Now call the method at offset VMTOFFSET[/i]
  CALL   DWORD PTR [EDX + VMTOFFSET TExample.VirtualMethod]
[b]end[/b];
Ich habs gerade mit dem edi Register anstatt des eax probiert. Dabei tritt jedoch eine AV auf.

Christian Seehase 4. Sep 2002 15:09

Moin jbg,

danke, dann ist es mir also nicht einfach entgangen.

Ich hoffe mal, dass sich das Problem mit der AV bei der Verwendung von EDI nur auf das zuletzt von Dir gepostete Beispiel beschränkt.
Da ich Assembler zur Beschleunigung von Stringverarbeitungen einsetzen will wäre das sonst ausgesprochen ungünstig (und irgendwie auch nicht zu erklären, denn dafür sind EDI/ESI schliesslich da)
Eine in sich abgeschlossene Routine, bei der also die Felder nur gelesen, aber nicht geschrieben werden müssen tuts anstandslos.
Dort verwende ich aber auch die Kombination mov EDI,self mov EDI,[EDI].FpWork usw.

Christian Seehase 4. Sep 2002 19:13

Moin jbg,

erst einmal vielen Dank für Deine Hilfe.
Leider hatte auch die Art, wie es in der Hilfe beschrieben wurde keinerlei Änderung gebracht.
Ich hab' die Lösung jetzt zwar gefunden, vermag aber nicht zu glauben, wie sich das Problem umgehen lässt:

Als der Fehler auftrat, sah' die Routine so aus:

Code:
[b]procedure[/b] TcsTranslator.AddToResult;
[b]asm[/b]
[color=#000080]// die eigentliche Routine[/color]
[b]end[/b];
wenn ich es hingegen so mache, funktionierts:
Code:
[b]procedure[/b] TcsTranslator.AddToResult;
[b]begin[/b]
[b]asm[/b]
[color=#000080]// die eigentliche Routine[/color]
[b]end[/b];
[b]end[/b];
Wenn ich jetzt noch das Warum wüsste...

OregonGhost 6. Sep 2002 09:15

Also, auf Anhieb würde ich als asm-Unkundiger raten, dass das erste eine reine Assembly-Funktion darstellt, während das zweite inline-Assembler in einer Object-Pascal-Funktion ist, und das Verhalten der beiden ist wohl etwas unterschiedlich... :angle2:

sakura 6. Sep 2002 09:44

In der zweiten Variante erstellt Delphi die Aufrufe zum Sichern von Registern (Rücksprungadresse) und lädt wohl die Adresse des Self.Objektes. Zusätzlich wird am Ende die Rücksprungadresse widerhergestellt und der RETurn durchgeführt.

Christian Seehase 6. Sep 2002 09:57

Moin OregonGhost,

ja, den Eindruck könnte man haben, nur ist es nicht entsprechend dokumentiert.

Die Hilfe meint dazu:

Zitat:

Zitat von Delphi 5 Hilfe
Mit dem integrierten Assembler können Sie komplette Prozeduren und Funktionen schreiben, für die keine begin...end-Anweisung erforderlich ist:

Scheint nur nicht zu stimmen, zumindest wenn es sich um Methoden handelt :shock:

Im CPU Fenster hab' ich's mir allerdings noch nicht angeschaut.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:30 Uhr.
Seite 1 von 2  1 2      

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