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 2 von 3     12 3      
Benutzerbild von FAlter
FAlter

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

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

  Alt 6. Mai 2008, 19:27
Hi,

danke. Ein kleiner Fehler: Es heißt UCS4String statt USC4String (war plötzlich ne rote Wellenlinie da).

Wie ich an deinem Code erkennen kann, werden wirklich Zeiger auf die Zeiger übergeben. Aber jetzt ist die Frage ja nicht mehr nötig. Zumindest, wenn es läuft - werds gleich mal testen.

Mfg
FAlter

[edit] Scheint zu funktionieren - und ich versteh sogar was, ist also nicht zu kompliziert geworden! [/edit]
Felix Alter
Japanurlaub 2015
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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

  Alt 6. Mai 2008, 19:44
ups: nja, hatte die UCS4String-Version ohne zu testen (um)geschrieben

PS: das "SHR 1" ist ein schnelles "div 2"
und es ist nötig, da die OleStr (ole32.dll) die Länge in Byte angibt.

und bei USC4 nicht, da Delphi bei seinen dynamischen Arrays (String, WideString, dynArray und Co.) die Anzahl der Elemente/Chars

PS: in FTypes.pas schau dir mal den Abschnitt "Compiler Intern Data-Types" (ab Zeile 1213) an
http://www.delphipraxis.net/internal...=879295#879295



bei "SwapString(Var S: WideString);" könnte man jetzt noch jeweils 2 Chars via BSWAP zusammen verarbeiten
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
 
#13

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

  Alt 6. Mai 2008, 19:57
Hi,

Zitat von himitsu:
PS: das "SHR 1" ist ein schnelles "div 2"
Ich weiß. Ich sag ja, ich versteh sie sogar

Zitat:
und es ist nötig, da die OleStr (ole32.dll) die Länge in Byte angibt.
Gut zu wissen.

Zitat:
PS: in FTypes.pas schau dir mal den Abschnitt "Compiler Intern Data-Types" (ab Zeile 1213) an
http://www.delphipraxis.net/internal...=879295#879295
Kann ich ja mal machen.


Zitat:
bei "SwapString(Var S: WideString);" könnte man jetzt noch jeweils 2 Chars via BSWAP zusammen verarbeiten
Macht BSwap nicht aus 01 02 | 03 04 ein 04 03 | 02 01? Wenn man da zwei 16-Bit-Werte zusammenfasst, sind die doch vertauscht? Ob man damit soviel besser kommt, danach nochmal die beiden tauschen zu müssen (zumal man nicht so ohne weiteres an die Bits 16..31 rankommt, wenns noch im e?x-Register steht)?

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

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

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

  Alt 6. Mai 2008, 20:05
besser kommt man in dem Sinne, daß nun integerweise gearbeitet wird, also mit 2*16 Bit ... wobei die 32 Bit-CPU da doch optimaler arbeitet
Delphi-Quellcode:
procedure SwapString(Var S: WideString);
asm
  mov eax, [eax]

  test eax, eax
  jz @exit

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

  push ecx
  shr ecx, 1

  jz @onechar

  @loop:

  mov edx, [eax]
  bswap edx
  rol edx, 16
  mov [eax], edx

  add eax, 4
  dec ecx
  jnz @loop

  @onechar:

  pop ecx
  and ecx, $01
  jz @exit

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

  @exit:
end;
ach, da ich eh grad etwas zuviel Zeit hatte (blöd, wenn man auf was warten muß )
ist aber noch ungetestet
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
 
#15

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

  Alt 6. Mai 2008, 20:18
Hi,

stimmt, wenn man es rotieren lässt, hat man die beiden Teile des DWords ja auch wider getauscht, insofern ist ein effizientes Tauschen dann möglich.

Evtl. könnte man das Label @onechar noch drei Anweisungen nach unten verschieben, denn wenn es nur ein Zeichen ist muss nicht nochmal geprüft werden, ob die Anzahl ungerade ist (ein Byte übrig bleibt), das ist dann nämlich eben der Fall.

Mfg
FAlter

[edit] Getestet mit verschobenem @onechar läuft nicht. Was hab ich da nur schon wieder übersehen? [/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
 
#16

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

  Alt 6. Mai 2008, 20:38
Mögliche Assembler-Version für UCS2-Swap:
Delphi-Quellcode:
procedure SwapWords(var AWords; ACount: LongWord); register;
asm
        mov ecx, edx
        jecxz @@exit
@@loop: ror word ptr [eax + ecx * 2 - 2], 8
        loop @@loop
@@exit:
end;

procedure TestSwapWords();
var
  Value: WideString;
begin
  Value :=
    #$4800#$6500#$6C00#$6C00#$6F00#$2C00#$2000 +
    #$5700#$6F00#$7200#$6C00#$6400#$2100;
  SwapWords(Value[1], Length(Value));
  ShowMessage(Value);
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
 
#17

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

  Alt 6. Mai 2008, 20:46
Hi,

sieht zwar kurz aus, aber himitsus Version ist schöner, da sie (1.) die Parameter verwendet, wie ich sie mir vorstelle (mit viel weniger Tipparbeit) und (2.) die loop-Anweisung unschön ist. Keine Ahnung, wer die überhaupt eingeführt hat jedenfalls ist sie nur dann empfehlenswert, wenn man Speicherplatz sparen will, ansonsten kommt man mit dec und jz besser (zumindest wars früher so, evtl. ist sie heute etwas optimiert worden).

Mfg
FAlter
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
 
#18

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

  Alt 6. Mai 2008, 21:25
Dann halt mit WideString und dec/jnz
Delphi-Quellcode:
procedure SwapUCS2(var AValue: WideString); register;
asm
        mov eax, [AValue]
        or eax, eax
        jz @@exit // Empty (nil)
        mov ecx, [eax - 4] // Relies on internal BSTR knowlegde!
        shr ecx, 1
// jz @@exit // Should not happen (Empty <> nil)
@@loop: dec ecx
        ror word ptr [eax + ecx * 2], 8
        jnz @@loop
@@exit:
end;
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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

  Alt 6. Mai 2008, 21:50
also ohne deine Signatur wär mir langsam was komisch vorgekommen (wo kommt denn das x-Anhänsel her?)

nja, gegen die Assemblerprofies hat man einfach keine Chance

dafür bin ich einfach zu sehr gedanklich in der Delphi-/Pascalschiene drin ... übersetze es sozusagen und versuch's dann zu optimieren...
Delphi-Quellcode:
procedure SwapString(Var S: WideString);
asm
  mov eax, [eax] // eax := PWideChar(S);
  test eax, eax // if eax = nil then goto @exit;
  jz @exit
  mov ecx, [eax - 4] // ecx = length(eax) {div 2};
  shr ecx, 1
  push ecx // temp := ecx;
  shr ecx, 1 // ecx := ecx div 2;
  jz @onechar // if ecx = 0 then goto @onechar;
  @loop: // @loop:
  mov edx, [eax] // PLongWord(eax)^ := bswap(PLongWord(eax)^) rol 16;
  bswap edx
  rol edx, 16
  mov [eax], edx
  add eax, 4 // inc(eac, 4);
  //dec ecx // //dec(ecx);
  //jnz @loo // //if ecx <> 0 then goto @loop;
  loop @loop // dec(ecx); if ecx <> 0 then goto @loop;
  @onechar: // @onechar:
  pop ecx // ecx := temp;
  and ecx, $01 // ecx := ecx and $01;
  jz @exit // if ecx = 0 then goto @exit;
  mov dx, [eax] // PWord(eax)^ := xchg(PWord(eax)^);
  xchg dl, dh
  mov [eax], dx
  @exit: // @exit:
end;
nja, zumindestens lerntman da auch immer was dazu.
wußte noch garnicht, daß man ROR/ROL nicht nur mit Register verwenden kann ...
schade, daß dieses nicht auch mit BSWAP geht, sonst würde ich brstimmt auch fast so weit runter(klein) kommen ^_^
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 nicodex
nicodex

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

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

  Alt 6. Mai 2008, 22:38
Wenn man davon ausgeht, dass UCS4String ein array of UCS4Char (dynamisches Array) ist, dann könnte man folgendes 'verbrechen':
Delphi-Quellcode:
procedure SwapUCS4(var AValue: UCS4String); register;
asm
        mov eax, [AValue]
        or eax, eax
        jz @@exit // Empty (nil)
        mov ecx, [eax - 4] // Relies on internal DynArray knowlegde!
// jecxz @@exit // Should not happen (Empty <> nil)
// dec ecx // Skip the terminating $00000000
// jz @@exit
@@loop: dec ecx
        mov edx, [eax + ecx * 4]
        bswap edx
        mov [eax + ecx * 4], edx
        jnz @@loop
@@exit:
end;

procedure TestSwapUCS4;
const
  Hello: array [0..13] of UCS4Char = (
    $48000000, $65000000, $6C000000, $6C000000, $6F000000, $2C000000, $20000000,
    $57000000, $6F000000, $72000000, $6C000000, $64000000, $21000000, $00000000
  );
var
  Value: UCS4String;
begin
  SetLength(Value, Length(Hello));
  Move(Hello[0], Value[0], SizeOf(Hello));
  SwapUCS4(Value);
  ShowMessage(UCS4StringToWideString(Value));
end;
Statt read/BSWAP/write hätte man an auch drei ROR (8/16/8) nehmen können:
Delphi-Quellcode:
procedure SwapUCS4(var AValue: UCS4String); register;
asm
        mov eax, [AValue]
        or eax, eax
        jz @@exit
        sub eax, 4
        mov ecx, [eax]
// dec ecx // Skip terminating $00000000
// jz @@exit
@@loop: add eax, 4
        dec ecx
        ror word ptr [eax], 8
        ror dword ptr [eax], 16
        ror word ptr [eax], 8
        jnz @@loop
@@exit:
end;
ps: das x kommt von nicodex (Vorname) / nicodex (Thema) / nicodex (Land) / nicodex (Neigung) / nicodex (Spiel) :]
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 21:37 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