Einzelnen Beitrag anzeigen

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