![]() |
Funktionen in Assembler unter Delphi 7
In früheren Zeiten, als die CPUs noch langsamer waren, als heute, wurde ja auf jedes kleine etwas geachtet, um CPU-Zeit einzusparen. Eine Möglichkeit in Turbo-Pascal und Delphi waren die Assembler-Functionen. Die gaben das Ergebnis direkt im AX-Register zurück. (Muss das heute evtl. EAX sein ?) Im folgenden zwei Functionen, mit denen jeweils das Hi- oder Lo-Word eines Longint-32bit-Wertes ausgelesen werden soll. Die Function bestand nur aus einem einzigen Assembler-Befehl.
Delphi-Quellcode:
Unter Delphi 7 bringt diese Function einen Laufzeitfehler. Ich habe sie folgendermassen abgeändert, damit es funktioniert. Es sind keine Assembler-Functionen mehr. Mit ASM wird nur noch auf local vereinbarte Variable zugegriffen.
Function HiWord(Zahl:Longint):Word; Assembler;
ASM MOV AX,Word Ptr [Zahl+2] End; Function LoWord(Zahl:Longint):Word; Assembler; ASM MOV AX,Word Ptr [Zahl+0] End;
Delphi-Quellcode:
Natürlich könnte man es auch anders und ohne ASM machen, meine Frage: kann ich im ASM-Bereich nicht mehr auf die übergebenen Parameter zugreifen ?
Function HiWord(pZahl:Longint):Word;
Var Zahl : Longint; hiZahl : Word; Begin Zahl := pZahl; ASM MOV AX,Word Ptr [Zahl+2] MOV [hiZahl],AX End; Result := hiZahl; End; Function LoWord(pZahl:Longint):Word; Var Zahl : Longint; loZahl : Word; Begin Zahl := pZahl; ASM MOV AX,Word Ptr [Zahl+0] MOV [loZahl],AX End; Result := loZahl; End; |
AW: Funktionen in Assembler unter Delphi 7
Deine Funktion versucht auf die Adresse Zahl + 2 zuzugreifen. Was du meinst ist die Adresse von Zahl + 2. Das kann so nicht funktionieren, egal wie du diese Assembleranweisung verpackst... denn der Parameter wird in einem Register übergeben. Da gibt es keine Adresse, die man erhöhen könnte...
Zudem liest du aus Zahl (also aus dem Register EAX) und schreibst in AX, also aus dem selben Register. Auch das geht nicht. Wenn das früher mal ging, war das eine andere Aufrufkonvention, die die Parameter auf den Stack gelegt hat. Gehen tut es so:
Delphi-Quellcode:
Oder du nutzt gleich Lo und Hi, die Delphi schon selbst kennt. Angesichts verschiedener Plattformen, die Delphi unterstützt, ist es auch die weit bessere Lösung ohne Assembler zu arbeiten wo das möglich ist.
function HiWord(const ANumber: Longint): Word; assembler;
asm shr ANumber, 16 end; function LoWord(const ANumber: Longint): Word; assembler; asm and ANumber, $FF end; |
AW: Funktionen in Assembler unter Delphi 7
Danke für Deine Antwort. Ich habe inzwischen auch herausbekommen, daß die Übergabewerte Longint im EAX bereitgestellt werden. Meine Funktionen sehen nun so aus und funktionieren.
Delphi-Quellcode:
Die beiden AND EAX,0FFFFh Befehle müssten nicht sein, da das Hi-Wort in EAX beim Ergebnis (WORD) keine Rolle spielt.
Function HiWord(pZahl:Longint):Word;
ASM PUSH EAX POP AX POP AX AND EAX,0FFFFh End; Function LoWord(pZahl:Longint):Word; ASM AND EAX,0FFFFh End; Sebastian, ich habe auch Deine Functionen probiert, dabei allerdings bei LoWord das Literal in $FFFF geändert, sonst wird ja nur das LoByte bereitgestellt. Wenn ich in der CPU debugge, sehe ich, daß die Variable ANumber tatsächlich das Register EAX ist. Es sind also immer noch die sehr schnellen 1-Befehl-Functionen, die man mit ASM machen kann, möglich. Zitat:
|
AW: Funktionen in Assembler unter Delphi 7
Zitat:
Delphi-Quellcode:
Function HiWord(pZahl:Longint):Word;
ASM SHR EAX,16 End; |
AW: Funktionen in Assembler unter Delphi 7
Das hatte ich ja schon oben geschrieben.
|
AW: Funktionen in Assembler unter Delphi 7
Zitat:
|
AW: Funktionen in Assembler unter Delphi 7
Zitat:
Zitat:
|
AW: Funktionen in Assembler unter Delphi 7
Geht auch komplett ohne Assembler und Bitoperationen (und vermutlich sogar schneller dank
Delphi-Quellcode:
) ;)
inline
Delphi-Quellcode:
Hoffe ich hab nicht wieder die Reihenfolge von Lo und Hi vertauscht...
type
// glaube so einen Datentyp hat Delphi bereits in irgendeiner // Unit (vermutlich Windows), weiß aber den Namen nicht. TDWord = packed record Lo, Hi: Word; end; function HiWord(Zahl: DWord): Word; inline; begin Result := TDWord(Zahl).Hi; end; Function LoWord(Zahl: DWord): Word; inline; begin Result := TDWord(Zahl).Lo; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:29 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