AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Optimallösung gesucht: Little Endian <-> Big Endian
Thema durchsuchen
Ansicht
Themen-Optionen

Optimallösung gesucht: Little Endian <-> Big Endian

Ein Thema von FAlter · begonnen am 6. Mai 2008 · letzter Beitrag vom 9. Mai 2008
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von FAlter
FAlter

Registriert seit: 21. Jul 2004
Ort: Ostfildern
1.095 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#1

Optimallösung gesucht: Little Endian <-> Big Endian

  Alt 6. Mai 2008, 16:58
Hi,

kann man das noch optimieren? (Kommentiert ist der Code, den Delphi erzeugt.)

Delphi-Quellcode:
procedure SwapBytes(var X: WideChar);
asm
  mov dx, [X] //mov dx, [eax]
  xchg dl, dh
  mov [X], dx //mov [eax], dx
end;

procedure SwapBytes(var X: UCS4Char);
asm
  mov edx, [X] //mov edx, [eax]
  bswap edx
  mov [X], edx //mov [eax], edx
end;
Und ich geh doch richtig davon aus, dass das, was übergeben wird, der Zeiger auf das Zeichen ist (wegen var)?

Mfg
FAlter
Felix Alter
Japanurlaub 2015
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Optimallösung gesucht: Little Endian <-> Big Endia

  Alt 6. Mai 2008, 17:25
1. x liegt in eax und du musst es nicht erst noch weiter herumschieben.
2. gibt es für 16bit noch die Delphi-Funktion swap. Die erzeugt direkt inline-Code.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.151 Beiträge
 
Delphi 12 Athens
 
#3

Re: Optimallösung gesucht: Little Endian <-> Big Endia

  Alt 6. Mai 2008, 17:39
@sirius: bei mir ist Swap 32 bit (Integer)
nja, aber es ist zumindestens noch eine Funktion ist
Delphi-Quellcode:
w := Swap(w);
// erzeugt aber das selbe Ergebnis wie
ByteSwap(w);
und als Inline ist es besser


aber nee, diesen Code kann man nicht mehr optimieren, (leider geht ja bei ASM kein Inline)
nur ein & könnte nicht schaden.
Delphi-Quellcode:
procedure SwapBytes(var X: WideChar);
asm
  mov dx, [&X]
  xchg dl, dh
  mov [&X], dx
end;

procedure SwapBytes(var X: UCS4Char);
asm
  mov edx, [&X]
  bswap edx
  mov [&X], edx
end;

// ohne BSWAP für alte CPUs
procedure SwapBytes(var X: UCS4Char);
asm
  mov edx, [&X]
  xchr dh, dl
  rol edx, 16
  xchg dh, dl
  mov [&X], edx
end;
was du optimieren könntest, wäre mehrere Zeichen umzuwandeln und nicht nur Eines.



aber wie meinst du das?
Zitat:
Kommentiert ist der Code, den Delphi erzeugt.


[add]
@sirius:
Delphi-Quellcode:
function SwapBytes(X: WideChar): WideChar;
asm
  xchg al, ah
end;

function SwapBytes(X: UCS4Char): UCS4Char;
asm
  bswap eax
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#4

Re: Optimallösung gesucht: Little Endian <-> Big Endia

  Alt 6. Mai 2008, 17:43
Ich denke er meint den Code aus der CPU-Ansicht vom Debugger.
  Mit Zitat antworten Zitat
Benutzerbild von FAlter
FAlter

Registriert seit: 21. Jul 2004
Ort: Ostfildern
1.095 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

Re: Optimallösung gesucht: Little Endian <-> Big Endia

  Alt 6. Mai 2008, 17:56
Hi,

Swap kannte ich noch nicht, hab gleich mal nachgesehen.

Aus der Delphi-Hilfe:
X ist ein Ausdruck des Typs SmallInt oder Word (16 Bit).

Ich hab aber WideChar. Notfalls gehts mit Typecasten.

Aus der Delphi-Hilfe:
Die Funktion ist nur aus Gründen der Abwärtskompatibilität vorhanden.


Na Toll. Dann so:

Delphi-Quellcode:
procedure SwapBytes(var X: WideChar); inline;
//Hinweis siehe unter der Prozedur!
begin
  X := WideChar(Swap(Word(X)));
end;
{

Sollte CodeGear "swap" eines Tages endgültig abschaffen, bitte das hier nutzen:

procedure SwapBytes(var X: WideChar);
asm
  mov  dx, [X] //mov dx, [eax]
  xchg  dl,  dh
  mov  [X],  dx //mov [eax], dx
end;

}
Wenigstens wird der Aufruf jetzt so übersetzt (Result ist WideString):

Code:
[b]FAUnicode.pas.137: SwapBytes(Result[I]);[/b]
0045949D 8B06             mov eax,[esi]
0045949F 8D4458FE        lea eax,[eax+ebx*2-$02]
004594A3 0FB708           movzx ecx,[eax]
004594A6 86E9             xchg cl,ch
004594A8 668908           mov [eax],cx
004594AB 43               inc ebx
Schade, dass Inline und Inline-Assembler ( ) sich nicht vertragen.

@roter Kasten: Es steht zwar als Integer in der OH, aber es steht auch darunter, was ich oben geschrieben habe: Smallint oder Word, also 16 Bit.

Das & braucht man bloß, wenns nicht eindeutig ist. Es gibt aber kein Register X, also wird der Parameter genommen. Wenn ich ihn ch für Char genannt hätte, müsste ich &Ch schreiben.

Für mehrere Zeichen müsste ich mich noch genauer mit dem Aufbau von Strings und der Übergabe von String-Parametern beschäftigen, dann kann ich auch gleich den ganzen String umwandeln (und dyn. Arrays, denn USC4String ist ein type array of USC4Char). Da es jedoch nur geschrieben wurde, weil ich es schnell brauchte und ich eigentlich was ganz anderes tun wollte, werd ich mich im Moment nicht groß in was einlesen, was ich noch nicht kann und mit dem ursprünglichen Thema nichts zu tun hat. Hab aber schon die TODO-Kommentare gesetzt. Evtl. hat ja hier jemand Langeweile.

Mit "wie es Delphi übersetzt" meine ich was der aus dem X macht. Erst hatte ich eax stehen aber das ging logischerweise nicht, da X als eax "übersetzt" wurde (der Parameter wurde also in eax übergeben). Aber das CPU-Fenster hat mir die Ursache gezeigt und ich bin auf (e)dx umgestiegen.

Das mit den Funktionen ist schon klar, dass die dann kürzer gehen (da ich dann keine Referenzen übergeben habe), aber das ist mehr Schreibarbeit. Wird es denn optimaler, wenn ich x := SwapBytes(x) schreibe? Kann sogar sein, wenn der Wert vorm Aufruf "zufällig" in (a)ax lag und später wieder dort gebraucht wird. Nur die Variante mit der obsolete-Funktion Swap ist so schon schnell genug, aber das als inline-Funktion zu schreiben macht auch keinen Unterschied.

Mfg
FAlter
Felix Alter
Japanurlaub 2015
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.151 Beiträge
 
Delphi 12 Athens
 
#6

Re: Optimallösung gesucht: Little Endian <-> Big Endia

  Alt 6. Mai 2008, 18:20
[edit] ups, ausversehn gelöscht ... wollte eigentlich zitieren, statt editieren
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von FAlter
FAlter

Registriert seit: 21. Jul 2004
Ort: Ostfildern
1.095 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#7

Re: Optimallösung gesucht: Little Endian <-> Big Endia

  Alt 6. Mai 2008, 18:44
Hi,

nochmal zum Thema optimieren, indem ich den ganzen String auf einmal bearbeite (vielleicht mach ich es ja doch schon jetzt):

Delphi-Quellcode:
procedure SwapBytes(var X: WideString);
procedure SwapBytes(var X: UCS4String);
Wird da jetzt ein Zeiger auf einen WideString (UCS4String), welcher wiederum ein Zeiger auf die Wide(UCS4)Chars ist, übergeben?

Mfg
FAlter

PS: Welche alten CPUs unterstützen denn kein bswap? Ich dachte immer, das gibts ab i80386DX (und was vor dem i486DX ist, ist eh egal, da lässt sich ja kein Win32 drauf installieren).
PPS: Ein WideString kat keinen Referenzzähler?

[edit] Es heißt UCS4String - sorry. Dann ist der Fehler weiter unten wohl auch ursprünglich meiner. [/edit]
Felix Alter
Japanurlaub 2015
  Mit Zitat antworten Zitat
Benutzerbild von nicodex
nicodex

Registriert seit: 2. Jan 2008
Ort: Darmstadt
286 Beiträge
 
Delphi 2007 Professional
 
#8

Re: Optimallösung gesucht: Little Endian <-> Big Endia

  Alt 6. Mai 2008, 19:01
Wenn die Delphi-Version Inline unterstützt, dann macht Assembler keinen Sinn mehr:
Delphi-Quellcode:
{$IFDEF BIG_ENDIAN}
type
  WordBE = Word;
{$ELSE ~BIG_ENDIAN}
function WordBE(AValue: Word): Word; inline;
begin
  Result := Swap(AValue);
end;
{$ENDIF BIG_ENDIAN}

procedure TForm20.FormCreate(Sender: TObject);
var
  Value: Word;
begin
  Value := WordBE($1234); // inlined: mov _x, $3412 !!!
  ShowMessage(IntToHex(Value, SizeOf(Value) * 2));
  Value := WordBE(Value); // inlined: xchg _l, _h
  ShowMessage(IntToHex(Value, SizeOf(Value) * 2));
end;
  Mit Zitat antworten Zitat
Benutzerbild von FAlter
FAlter

Registriert seit: 21. Jul 2004
Ort: Ostfildern
1.095 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#9

Re: Optimallösung gesucht: Little Endian <-> Big Endia

  Alt 6. Mai 2008, 19:15
Hi,

darum habe ich ja, wie in #5 geschrieben, die Funktion abgewandelt als inline mit swap. Das betrifft aber erstens noch nicht die 4-Byte-Variante und zweitens kann man evtl. noch was rausholen, wenn man die ganzen Strings umwandelt.

Mfg
FAlter
Felix Alter
Japanurlaub 2015
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.151 Beiträge
 
Delphi 12 Athens
 
#10

Re: Optimallösung gesucht: Little Endian <-> Big Endia

  Alt 6. Mai 2008, 19:18
WideString+Ref: nein, denn Delphi leitet den Widestring an OleStr weiter und der kennt keine Refferenzzählung.

'ne "einfache" Lösung wäre:

Delphi-Quellcode:
procedure SwapString(Var S: WideString);
asm
  mov eax, [eax]

  test eax, eax
  jz @exit

  mov ecx, [eax - 4]
  shr ecx, 1

  @loop:

  mov dx, [eax]
  xchg dl, dh
  mov [eax], dx

  add eax, 2
  dec ecx
  jnz @loop

  @exit:
end;

procedure SwapString(Var S: UCS4String);
asm
  mov eax, [eax]

  test eax, eax
  jz @exit

  mov ecx, [eax - 4]

  @loop:

  mov edx, [eax]
  bswap edx
  mov [eax], edx

  add eax, 4
  dec ecx
  jnz @loop

  @exit:
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 12:54 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