![]() |
Fehler beim Byte-Swap mit Assembler in Delphi
Delphi-Quellcode:
Mein Assembler ist ziemlich Eingerostet, das sollte aber doch so stimmen oder ?
function SwapDWord(DW: DWord): DWord;
begin asm mov eax, [DW] // Register EAX mit Wert von DW füllen // <- ... Inline Assembler Syntaxfehler bswap eax // Byte-Swap durchfhüren mov [DW], eax // Wert aus EAX zurück nach DW schreiben end; Result := DW; end; |
Re: Fehler beim Byte-Swap mit Assembler in Delphi
Beschäftige dich mit der Aufrufkonvention register (1. Parameter in EAX, Rückgabe in EAX glaub' ich zumindestens) :zwinker:
|
Re: Fehler beim Byte-Swap mit Assembler in Delphi
Delphi-Quellcode:
Viel Spaß ;)
function SwapDWord(DW: DWord): DWord;
asm bswap eax // Byte-Swap durchführen end; Und wenn wir schon dabei sind: [DW] wäre die Adresse auf welche DW zeigt. Und zwar das DWORD an dieser Stelle, weil der Zieloperand die Größe vorgibt ;) Ach ja und Delphi 4 kennt z.B. noch nicht BSWAP. Da heißt es dann:
Delphi-Quellcode:
So habe ich es bei der Native API-Unit der JEDIs gelöst:
function SwapDWord(DW: DWord): DWord;
asm db 0Fh, 0C8h // "bswap EAX" can only be executed on 486+!!! end;
Delphi-Quellcode:
(* Own function to swap bytes in 32bit values
The RtlUlongByteSwap routine converts a ULONG from little-endian to big-endian, and vice versa. *) function RtlUlongByteSwap(Source:ULONG):ULONG; asm // This is not written as mnemonics to be compatible with D4! db 0Fh, 0C8h // "bswap EAX" can only be executed on 486+!!! (* // Does the same but perhaps slower ... // Source = $11223344 rol AX, 08h // Source = $11224433 rol EAX, 0Fh // Source = $44331122 rol AX, 08h // Source = $44332211 *) end; |
Re: Fehler beim Byte-Swap mit Assembler in Delphi
Falls du es noch für ULONGLONG (LARGE_INTEGER/ULARGE_INTEGER) brauchst:
Delphi-Quellcode:
Ach Quark ... für die Vollständigkeit noch 16bit-Werte:
(* Own function to swap bytes in 64bit values
The RtlUlonglongByteSwap routine converts a ULONGLONG from little-endian to big-endian, and vice versa. *) function RtlUlonglongByteSwap(Source:ULONGLONG):ULONGLONG; asm mov EAX, [ESP+0Ch] // Get the high part of the ULONGLONG into EAX mov EDX, [ESP+08h] // Get the low part of the ULONGLONG into EDX // This is not written as mnemonics to be compatible with D4! db 0Fh, 0C8h // "bswap EAX" can only be executed on 486+!!! db 0Fh, 0CAh // "bswap EDX" can only be executed on 486+!!! // High part returns in EDX, low part in EAX end;
Delphi-Quellcode:
Ach ja, der Code ist JEDI-kompatibel unter MPL. Aber da ich der Urheber bin ;) ...
(* Own function to swap bytes in 16bit values
The RtlUshortByteSwap routine converts a USHORT from little-endian to big-endian, and vice versa. *) function RtlUshortByteSwap(Source:USHORT):USHORT; asm rol AX, 08h end; |
Re: Fehler beim Byte-Swap mit Assembler in Delphi
Delphi-Quellcode:
Hatte ich gerade so, dachte man muss erst etwas zuweisen.
function SwapDWord(DW: DWord): DWord;
asm bswap eax // Byte-Swap durchführen end; muss man also z.B. so sreiben:
Delphi-Quellcode:
// summe = summe + Value;
add eax, [Value] // oder so? add eax, Value |
Re: Fehler beim Byte-Swap mit Assembler in Delphi
Zitat:
Delphis register ist fast wie __fastcall in C. Der erste Wert kommt in EAX, der zweite in ECX, der dritte in EDX, der Rest auf dem Stack, wenn ich nicht irre. Außerdem werden 32bit-Werte in EAX übergeben. 64bit in EAX:EDX. Reihenfolge nachträglich korrigiert! Die OH sagt dazu: You can write complete procedures and functions using inline assembler code, without including a begin...end statement. For example,
Delphi-Quellcode:
The compiler performs several optimizations on these routines:
function LongMul(X, Y: Integer): Longint;
asm MOV EAX,X IMUL Y end; No code is generated to copy value parameters into local variables. This affects all string-type value parameters and other value parameters whose size isn’t 1, 2, or 4 bytes. Within the routine, such parameters must be treated as if they were var parameters. Unless a function returns a string, variant, or interface reference, the compiler doesn’t allocate a function result variable; a reference to the @Result symbol is an error. For strings, variants, and interfaces, the caller always allocates an @Result pointer. The compiler generates no stack frame for routines that aren’t nested and have no parameters or local variables. The automatically generated entry and exit code for the routine looks like this:
Delphi-Quellcode:
If locals include variants, long strings, or interfaces, they are initialized to zero but not finalized.
PUSH EBP ;Present if Locals <> 0 or Params <> 0
MOV EBP,ESP ;Present if Locals <> 0 or Params <> 0 SUB ESP,Locals ;Present if Locals <> 0 ... MOV ESP,EBP ;Present if Locals <> 0 POP EBP ;Present if Locals <> 0 or Params <> 0 RET Params ;Always present Locals is the size of the local variables and Params is the size of the parameters. If both Locals and Params are zero, there is no entry code, and the exit code consists simply of a RET instruction. Assembler functions return their results as follows. Ordinal values are returned in AL (8-bit values), AX (16-bit values), or EAX (32-bit values). Real values are returned in ST(0) on the coprocessor’s register stack. (Currency values are scaled by 10000.) Pointers, including long strings, are returned in EAX. Short strings and variants are returned in the temporary location pointed to by @Result. |
Re: Fehler beim Byte-Swap mit Assembler in Delphi
Super, Danke!
Richtige Profis hier ! |
Re: Fehler beim Byte-Swap mit Assembler in Delphi
Das mit dem BSWAP alleine funktioniert nicht wenn man die Optimierung ausschaltet und die Stackframes ein (beispielsweise fuer Debugging).
Der Compiler laesst es naemlich dann mit der Register-Calling-Convention sein und der erste Parameter steht nicht mehr in EAX. Die Jedi-Funktionen (aus der jedi-apilib) wandern demnaechst in die JCL wo sie hingehoeren. |
Re: Fehler beim Byte-Swap mit Assembler in Delphi
Zitat:
Zitat:
|
AW: Fehler beim Byte-Swap mit Assembler in Delphi
Moin moin,
ich hol den Thread hier mal aus der Versendkung... Wie sieht es mit der Funktion unter XE2 aus => Funktioniert diese unter einem 64bit noch genauso bzw. was muss geändert werden?
Delphi-Quellcode:
(Ich kann es nicht selber testen und habe dazu noch wenig Ahnung von ASM)
function SwapDWord(DW: DWord): DWord;
asm bswap eax // Byte-Swap durchführen end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:52 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