AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Fehler beim Byte-Swap mit Assembler in Delphi
Thema durchsuchen
Ansicht
Themen-Optionen

Fehler beim Byte-Swap mit Assembler in Delphi

Ein Thema von turboPASCAL · begonnen am 1. Jul 2005 · letzter Beitrag vom 29. Feb 2012
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#1

Fehler beim Byte-Swap mit Assembler in Delphi

  Alt 1. Jul 2005, 22:39
Delphi-Quellcode:
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;
Mein Assembler ist ziemlich Eingerostet, das sollte aber doch so stimmen oder ?
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Phistev
(Gast)

n/a Beiträge
 
#2

Re: Fehler beim Byte-Swap mit Assembler in Delphi

  Alt 1. Jul 2005, 22:44
Beschäftige dich mit der Aufrufkonvention register (1. Parameter in EAX, Rückgabe in EAX glaub' ich zumindestens)
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#3

Re: Fehler beim Byte-Swap mit Assembler in Delphi

  Alt 1. Jul 2005, 22:48
Delphi-Quellcode:
function SwapDWord(DW: DWord): DWord;
asm
  bswap eax // Byte-Swap durchführen
end;
Viel Spaß

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:
function SwapDWord(DW: DWord): DWord;
asm
  db 0Fh, 0C8h // "bswap EAX" can only be executed on 486+!!!
end;
So habe ich es bei der Native API-Unit der JEDIs gelöst:
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;
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#4

Re: Fehler beim Byte-Swap mit Assembler in Delphi

  Alt 1. Jul 2005, 22:56
Falls du es noch für ULONGLONG (LARGE_INTEGER/ULARGE_INTEGER) brauchst:

Delphi-Quellcode:
(* 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;
Ach Quark ... für die Vollständigkeit noch 16bit-Werte:

Delphi-Quellcode:
(* 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;
Ach ja, der Code ist JEDI-kompatibel unter MPL. Aber da ich der Urheber bin ...
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#5

Re: Fehler beim Byte-Swap mit Assembler in Delphi

  Alt 1. Jul 2005, 22:59
Delphi-Quellcode:
function SwapDWord(DW: DWord): DWord;
asm
  bswap eax // Byte-Swap durchführen
end;
Hatte ich gerade so, dachte man muss erst etwas zuweisen.

muss man also z.B. so sreiben:
Delphi-Quellcode:
// summe = summe + Value;

add eax, [Value]
// oder so?
add eax, Value
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#6

Re: Fehler beim Byte-Swap mit Assembler in Delphi

  Alt 1. Jul 2005, 23:04
Zitat von turboPASCAL:
Delphi-Quellcode:
// summe = summe + Value;

add eax, [Value]
// oder so?
add eax, Value
Das kommt immer darauf an. Wenn Value als var/const übergeben wird, kann das sein.

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:
function LongMul(X, Y: Integer): Longint;   

asm
  MOV EAX,X
  IMUL Y
end;
The compiler performs several optimizations on these routines:

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:
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
If locals include variants, long strings, or interfaces, they are initialized to zero but not finalized.

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.
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#7

Re: Fehler beim Byte-Swap mit Assembler in Delphi

  Alt 1. Jul 2005, 23:08
Super, Danke!

Richtige Profis hier !
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#8

Re: Fehler beim Byte-Swap mit Assembler in Delphi

  Alt 2. Jul 2005, 06:23
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.
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#9

Re: Fehler beim Byte-Swap mit Assembler in Delphi

  Alt 2. Jul 2005, 10:11
Zitat von Robert Marquardt:
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.
... muß man denen wohl immer explizit register hintanstellen oder was? Kann ich mir eigentlich nicht vorstellen, weil's für den Debugger keinen Vorteil bringt. Ich bitte um PM zum Thema, damit ich einen Bugfix erarbeiten und einchecken kann.

Zitat von Robert Marquardt:
Die Jedi-Funktionen (aus der jedi-apilib) wandern demnaechst in die JCL wo sie hingehoeren.
Watt? Wieso? Häh? Das sind doch 2 komplett verschiedene Projekte.
  Mit Zitat antworten Zitat
Benutzerbild von x000x
x000x

Registriert seit: 21. Jan 2004
Ort: Bei Hamburg
308 Beiträge
 
Delphi XE2 Professional
 
#10

AW: Fehler beim Byte-Swap mit Assembler in Delphi

  Alt 28. Feb 2012, 10:20
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:
function SwapDWord(DW: DWord): DWord;
asm
  bswap eax // Byte-Swap durchführen
end;
(Ich kann es nicht selber testen und habe dazu noch wenig Ahnung von ASM)
Peter
-= Gruss Peter =-
-= alias x000x =-
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:12 Uhr.
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