Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   [Assembler]: 2 Variabeln austauschen (https://www.delphipraxis.net/74916-%5Bassembler%5D-2-variabeln-austauschen.html)

St.Pauli 10. Aug 2006 20:11


[Assembler]: 2 Variabeln austauschen
 
Hallo,

mein Vorhaben scheint einfach - ist es für mich zumindestens nicht. :lol:
Ich wollte ein bisschen mit Inline-Assembler in Delphi rumspielen und eine Procedure schreiben,
welche mir meine 2 Variablen vertauscht.

Innerhalb meines Programmes klappt es wunderbar:

Delphi-Quellcode:
 
var
  a, b : longword;
begin
  a := 10;
  b := 20;
  asm
    MOV  EAX, a
    XCHG EAX, b
    MOV  a, EAX
  end;
Nur wie kann ich den ganzen Assembler-Teil jetzt in eine Procedure auslagern? Ich bekomme es einfach nicht gebacken...
Ich hoffe ihr könnt mir weiterhelfen...

JasonDX 10. Aug 2006 20:22

Re: [Assembler]: 2 Variabeln austauschen
 
Wenn du es in eine Prozedur auslagerst, musst du auf Delphis CallingConventions achten. D.h. es wird nicht wie beim stdcall alles auf den Stack gepusht, sondern zuerst wird eax, edx und ecx gefuellt.
D.h. mit diesem Prozedurkopf
Delphi-Quellcode:
procedure Switch(a, b: integer);
wird dir a in eax, und b in edx geschoben. Allerdings musst du die Parameter per Call by Reference uebergeben, da die veraenderung auch uebernommen werden soll, also so:
Delphi-Quellcode:
procedure Switch(var a, b: integer);
Das aendert nur so viel, dass nicht der Wert, sondern die Adressen der Variablen mitgegeben werden.
Zu deutsch wuerde deine Prozedur dann so aussehn:
Delphi-Quellcode:
procedure Switch(var a, b: integer);
asm
  mov ecx, [eax]
  xchg [edx], ecx
  mov [eax], ecx
end;
Du musst vorher den Wert von a ([eax]) in ecx schreiben, da du nicht 2 Parameter gleichzeitig dereferenzieren kannst.

greetz
Mike

St.Pauli 10. Aug 2006 20:36

Re: [Assembler]: 2 Variabeln austauschen
 
Es funktioniert perfekt! Danke für die schnelle Lösung und die ausführliche Beschreibung!!! :thumb:

Hawkeye219 10. Aug 2006 21:07

Re: [Assembler]: 2 Variabeln austauschen
 
Hallo St.Pauli,

hast du einmal getestet, ob die vorgestellte Assembler-Version wirklich schneller ist als eine reine PASCAL-Version? Die folgende Routine sollte etwas schneller sein:

Delphi-Quellcode:
procedure Switch (var a, b: integer);
asm
  push ebx
  mov ecx,[eax]
  mov ebx,[edx]
  mov [edx],ecx
  mov [eax],ebx
  pop ebx
end;
Eine reine PASCAL-Lösung ist übrigens etwa gleich schnell. Da du in deinem Profil "Delphi 2005" angibst, könntest du aber mit einer INLINE-Prozedur noch etwas Zeit einsparen:

Delphi-Quellcode:
procedure Switch (var a, b: Integer); inline;
var
  t : Integer;
begin
  t := a;
  a := b;
  b := t;
end;
Gruß Hawkeye

JasonDX 10. Aug 2006 21:30

Re: [Assembler]: 2 Variabeln austauschen
 
Zitat:

Zitat von Hawkeye219
Die folgende Routine sollte etwas schneller sein:

Delphi-Quellcode:
procedure Switch (var a, b: integer);
asm
  push ebx
  mov ecx,[eax]
  mov ebx,[edx]
  mov [edx],ecx
  mov [eax],ebx
  pop ebx
end;

Es geht noch schneller ^^
Delphi-Quellcode:
procedure Switch (var a, b: integer);
asm
  push [eax]
  mov ecx, [edx]
  mov [eax], ecx
  pop [edx]
end;
Aber ich glaube, die Geschwindigkeitsunterschiede sind hier sehr gering, sodass sie kaum ins Gewicht fallen ;)

greetz
Mike

St.Pauli 10. Aug 2006 21:39

Re: [Assembler]: 2 Variabeln austauschen
 
OK, ich habe mal alle 3 Proceduren getestet:
  • JasonDX: ~140 ms
  • Hawkeye219 in Assembler: ~46 ms
  • Hawkeye219 ohne Assembler: ~15 ms
Tatsächlich ist die Inline-Procedure am schnellsten!!! Aber Jason hat recht. Um überhaupt eine Differenz zu bekommen musste ich enorm viele Durchläufe durchführen, was den Zeitvorteil zunichte macht, da ich die Procedure nur ein paar Mal aufrufen muss...

Egal, jetzt habe ich die Qual der Wahl zwischen den 3 Versionen :mrgreen:

JasonDX 10. Aug 2006 21:49

Re: [Assembler]: 2 Variabeln austauschen
 
Zitat:

Zitat von St.Pauli
OK, ich habe mal alle 3 Proceduren getestet:
  • JasonDX: ~140 ms
  • Hawkeye219 in Assembler: ~46 ms
  • Hawkeye219 ohne Assembler: ~15 ms

Ich schaetze, du hast die obere meiner Funktionen genommen (d.h. nicht die aus meinem 2. Beitrag im Thread), denn ansonsten wuerde mich das Ergebnis wundern ^^

Zitat:

Zitat von St.Pauli
Tatsächlich ist die Inline-Procedure am schnellsten!!!

Das war zu erwarten. ;) Bei einem Prozeduraufruf geschieht ziemlich viel, man sehe sich das CPU-Debugfenster an ;)
Eine Inline-Function erspart sich die ganze Pusherei auf den Stack, was einen enormen Geschwindigkeitsschub gibt. :)
Interessant waere noch, was eine asm-inline-Funktion ergeben wuerde. Ich hab derzeit leider nur D7 drauf, da gibts noch kein inline :(

greetz
Mike

Dax 10. Aug 2006 21:50

Re: [Assembler]: 2 Variabeln austauschen
 
In Inline-Methoden darf man keine Assembler-Befehle benutzen. Hab ich früher mal schmerzlich gemerkt, das Inline weggenommen, Assemblerbefehle reingebaut und mich gefreut, das es am Ende doch schneller war ;)

Hawkeye219 10. Aug 2006 22:01

Re: [Assembler]: 2 Variabeln austauschen
 
Zitat:

Zitat von JasonDX
Zitat:

Zitat von St.Pauli
Tatsächlich ist die Inline-Procedure am schnellsten!!!

Das war zu erwarten. ;) Bei einem Prozeduraufruf geschieht ziemlich viel, man sehe sich das CPU-Debugfenster an ;)
Eine Inline-Function erspart sich die ganze Pusherei auf den Stack, was einen enormen Geschwindigkeitsschub gibt.

Genau darum ging es mir eigentlich. Ich habe in der Vergangenheit auch häufiger versucht, durch Assemblerroutinen einen Geschwindigkeitsvorteil zu erlangen, und bin dabei in einige Fallen getappt (z.B. die extrem langsame XCHG-Anweisung bei Speicheroperanden). Seitdem es INLINE gibt, trete ich nur noch äußerst selten gegen den Compiler an...

Gruß Hawkeye

Namenloser 11. Aug 2006 00:18

Re: [Assembler]: 2 Variabeln austauschen
 
Öhm, was bewirkt eigentlich Inline? Kann man das bei jeder Methode verwenden? Bringt es bei jeder Methode inen Geschwindigkeits-Boost? Achgottchen, das wär ja schön :stupid: :drunken:


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:40 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