![]() |
[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:
Nur wie kann ich den ganzen Assembler-Teil jetzt in eine Procedure auslagern? Ich bekomme es einfach nicht gebacken... var a, b : longword; begin a := 10; b := 20; asm MOV EAX, a XCHG EAX, b MOV a, EAX end; Ich hoffe ihr könnt mir weiterhelfen... |
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:
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:
procedure Switch(a, b: integer);
Delphi-Quellcode:
Das aendert nur so viel, dass nicht der Wert, sondern die Adressen der Variablen mitgegeben werden.
procedure Switch(var a, b: integer);
Zu deutsch wuerde deine Prozedur dann so aussehn:
Delphi-Quellcode:
Du musst vorher den Wert von a ([eax]) in ecx schreiben, da du nicht 2 Parameter gleichzeitig dereferenzieren kannst.
procedure Switch(var a, b: integer);
asm mov ecx, [eax] xchg [edx], ecx mov [eax], ecx end; greetz Mike |
Re: [Assembler]: 2 Variabeln austauschen
Es funktioniert perfekt! Danke für die schnelle Lösung und die ausführliche Beschreibung!!! :thumb:
|
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:
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:
procedure Switch (var a, b: integer);
asm push ebx mov ecx,[eax] mov ebx,[edx] mov [edx],ecx mov [eax],ebx pop ebx end;
Delphi-Quellcode:
Gruß Hawkeye
procedure Switch (var a, b: Integer); inline;
var t : Integer; begin t := a; a := b; b := t; end; |
Re: [Assembler]: 2 Variabeln austauschen
Zitat:
Delphi-Quellcode:
Aber ich glaube, die Geschwindigkeitsunterschiede sind hier sehr gering, sodass sie kaum ins Gewicht fallen ;)
procedure Switch (var a, b: integer);
asm push [eax] mov ecx, [edx] mov [eax], ecx pop [edx] end; greetz Mike |
Re: [Assembler]: 2 Variabeln austauschen
OK, ich habe mal alle 3 Proceduren getestet:
Egal, jetzt habe ich die Qual der Wahl zwischen den 3 Versionen :mrgreen: |
Re: [Assembler]: 2 Variabeln austauschen
Zitat:
Zitat:
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 |
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 ;)
|
Re: [Assembler]: 2 Variabeln austauschen
Zitat:
Gruß Hawkeye |
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:
|
Re: [Assembler]: 2 Variabeln austauschen
Zitat:
Zitat:
Zitat:
Hier mal ein Auszug aus meinem Code aus den Indy-Komponentnen (IdGlobal.pas). Würden die lokalen Find() und FindNext() ge-inlined wäre der Code um ein ganzes Stück langsamer, weil der Compiler das ESI Register im Inline-Code nicht verweden kann und somit bei jedem Schleifendurchlauf den PChar-Zeiger neu aus dem Speicher einliest und danach wieder dorthin schreibt (2 Speicherzugriffe mehr pro Schleifendurchlauf).
Delphi-Quellcode:
function PosIdx(const ASubStr, AStr: AnsiString; AStartPos: Cardinal): Cardinal;
// use best register allocation on Win32 function Find(AStartPos, EndPos: Cardinal; StartChar: AnsiChar; const AStr: AnsiString): Cardinal; begin for Result := AStartPos to EndPos do if AStr[Result] = StartChar then Exit; Result := 0; end; // use best register allocation on Win32 function FindNext(AStartPos, EndPos: Cardinal; const AStr, ASubStr: AnsiString): Cardinal; begin for Result := AStartPos + 1 to EndPos do if AStr[Result] <> ASubStr[Result - AStartPos + 1] then Exit; Result := 0; end; var StartChar: AnsiChar; LenSubStr, LenStr: Cardinal; EndPos: Cardinal; begin if AStartPos = 0 then AStartPos := 1; Result := 0; LenSubStr := Length(ASubStr); LenStr := Length(AStr); if (LenSubStr = 0) or (AStr = '') or (LenSubStr > LenStr - (AStartPos - 1)) then Exit; StartChar := ASubStr[1]; EndPos := LenStr - LenSubStr + 1; if LenSubStr = 1 then Result := Find(AStartPos, EndPos, StartChar, AStr) else begin repeat Result := Find(AStartPos, EndPos, StartChar, AStr); if Result = 0 then Break; AStartPos := Result; Result := FindNext(Result, AStartPos + LenSubStr - 1, AStr, ASubStr); if Result = 0 then begin Result := AStartPos; Exit; end else Inc(AStartPos); until False; end; end; |
Re: [Assembler]: 2 Variabeln austauschen
Vielen dank :-D
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:33 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