## 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 ).

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.