2010. január 27., szerda

How to reverse the byte order of integer values of all sizes


Problem/Question/Abstract:

I need to reverse the byte order of various integer values for an application. What would be the best way to do this big-endian/ little-endian swap? Note: I need to convert values of all sizes (word .. int64 ).

Answer:

Solve 1:

function EndianWord(w: word): word;
begin
  result := swap(w);
end;

function EndianInt(i: integer): integer;
begin
  result := swap(i);
end;

function EndianLong(L: longint): longint;
begin
  result := swap(L shr 16) or (longint(swap(L and $FFFF)) shl 16);
end;


Solve 2:

One could use the Swap function, but the problem with it is that it only swaps words or integers. I wrote thefollowing function to swap anything:

procedure SwapBytes(var Bytes; Len: Integer);
var
  Swapped: PChar;
  i: Integer;
begin
  GetMem(Swapped, Len);
  try
    for i := 0 to Len - 1 do
      Swapped[Len - i - 1] := PChar(@Bytes)[i];
    Move(Swapped^, Bytes, Len);
  finally
    FreeMem(Swapped);
  end;
end;

Usage:

SwapBytes(i, sizeof(i));


Solve 3:

unit Swap;

interface

type
  TData1 = word; {Is actually 2 bytes for alignment}
  TData2 = word;
  TData4 = cardinal;
  TData8 = double;
  PData2 = ^TData2;

function Swap2(a: cardinal): word;
function Swap4(a: cardinal): cardinal;
function Swap2Signed(a: cardinal): smallint;
function Swap4Signed(a: cardinal): longint;
procedure Swap4Array(a, b: pointer; n: integer);
procedure Swap2Array(a, b: pointer; n: integer);
procedure SwapDoubleTo8(const a: double; var b: TData8);
function Swap8ToDouble(var a: TData8): double;

implementation

function Swap2(a: cardinal): word;
asm
  bswap eax
  shr eax,16
end;

function Swap2signed(a: cardinal): smallint;
asm
  bswap eax
  shr eax,16
end;

function Swap4(a: cardinal): cardinal;
asm
  bswap eax
end;

function Swap4Signed(a: cardinal): longint;
asm
  bswap eax
end;

procedure Swap2Array(a, b: pointer; n: integer);
asm
  push ebx
  xor ebx, ebx
  lea eax, [eax + ecx * 2]
  lea edx, [edx + ecx * 2]
  sub ebx, ecx
  @L1:
  mov cx, word ptr[eax + ebx * 2]
  bswap cx
  mov word ptr[edx + ebx * 2], cx
  inc ebx
  jnz @L1
  pop ebx
end;

procedure Swap4Array(a, b: pointer; n: integer);
asm
  push ebx
  xor ebx, ebx
  lea eax, [eax + ecx * 4]
  lea edx, [edx + ecx * 4]
  sub ebx, ecx
  @L1:
  mov ecx, dword ptr[eax + ebx * 4]
  bswap ecx
  mov dword ptr[edx + ebx * 4], ecx
  inc ebx
  jnz @L1
  pop ebx
end;

procedure SwapDoubleTo8(const a: double; var b: TData8);
asm
  mov edx, dword ptr[a]
  mov ecx, dword ptr[a + 4]
  bswap edx
  bswap ecx
  mov dword ptr [eax], ecx
  mov dword ptr [eax + 4], edx
end;

function Swap8ToDouble(var a: TData8): double;
var
  hold: double;
asm
  mov edx, dword ptr[eax]
  mov ecx, dword ptr[eax + 4]
  bswap edx
  bswap ecx
  mov dword ptr [hold], ecx
  mov dword ptr [hold + 4], edx
  fld hold;
end;

procedure SwapInt64To8(const a: int64; var b: TData8);
asm
  mov edx, dword ptr[a]
  mov ecx, dword ptr[a + 4]
  bswap edx
  bswap ecx
  mov dword ptr [eax], ecx
  mov dword ptr [eax + 4], edx
end;

function Swap8ToInt64(var a: TData8): int64;
asm
  mov edx, dword ptr[eax + 4]
  mov eax, dword ptr[eax]
  bswap edx
  bswap eax
end;

end.

Nincsenek megjegyzések:

Megjegyzés küldése