Author: Jonas Bilinkevicius
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:
1
2 function EndianWord(w: word): word;
3 begin
4 result := swap(w);
5 end;
6
7 function EndianInt(i: integer): integer;
8 begin
9 result := swap(i);
10 end;
11
12 function EndianLong(L: longint): longint;
13 begin
14 result := swap(L shr 16) or (longint(swap(L and $FFFF)) shl 16);
15 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:
16
17 procedure SwapBytes(var Bytes; Len: Integer);
18 var
19 Swapped: PChar;
20 i: Integer;
21 begin
22 GetMem(Swapped, Len);
23 try
24 for i := 0 to Len - 1 do
25 Swapped[Len - i - 1] := PChar(@Bytes)[i];
26 Move(Swapped^, Bytes, Len);
27 finally
28 FreeMem(Swapped);
29 end;
30 end;
31
32 Usage:
33
34 SwapBytes(i, sizeof(i));
35
36
37 Solve 3:
38
39 unit Swap;
40
41 interface
42
43 type
44 TData1 = word; {Is actually 2 bytes for alignment}
45 TData2 = word;
46 TData4 = cardinal;
47 TData8 = double;
48 PData2 = ^TData2;
49
50 function Swap2(a: cardinal): word;
51 function Swap4(a: cardinal): cardinal;
52 function Swap2Signed(a: cardinal): smallint;
53 function Swap4Signed(a: cardinal): longint;
54 procedure Swap4Array(a, b: pointer; n: integer);
55 procedure Swap2Array(a, b: pointer; n: integer);
56 procedure SwapDoubleTo8(const a: double; var b: TData8);
57 function Swap8ToDouble(var a: TData8): double;
58
59 implementation
60
61 function Swap2(a: cardinal): word;
62 asm
63 bswap eax
64 shr eax,16
65 end;
66
67 function Swap2signed(a: cardinal): smallint;
68 asm
69 bswap eax
70 shr eax,16
71 end;
72
73 function Swap4(a: cardinal): cardinal;
74 asm
75 bswap eax
76 end;
77
78 function Swap4Signed(a: cardinal): longint;
79 asm
80 bswap eax
81 end;
82
83 procedure Swap2Array(a, b: pointer; n: integer);
84 asm
85 push ebx
86 xor ebx, ebx
87 lea eax, [eax + ecx * 2]
88 lea edx, [edx + ecx * 2]
89 sub ebx, ecx
90 @L1:
91 mov cx, word ptr[eax + ebx * 2]
92 bswap cx
93 mov word ptr[edx + ebx * 2], cx
94 inc ebx
95 jnz @L1
96 pop ebx
97 end;
98
99 procedure Swap4Array(a, b: pointer; n: integer);
100 asm
101 push ebx
102 xor ebx, ebx
103 lea eax, [eax + ecx * 4]
104 lea edx, [edx + ecx * 4]
105 sub ebx, ecx
106 @L1:
107 mov ecx, dword ptr[eax + ebx * 4]
108 bswap ecx
109 mov dword ptr[edx + ebx * 4], ecx
110 inc ebx
111 jnz @L1
112 pop ebx
113 end;
114
115 procedure SwapDoubleTo8(const a: double; var b: TData8);
116 asm
117 mov edx, dword ptr[a]
118 mov ecx, dword ptr[a + 4]
119 bswap edx
120 bswap ecx
121 mov dword ptr [eax], ecx
122 mov dword ptr [eax + 4], edx
123 end;
124
125 function Swap8ToDouble(var a: TData8): double;
126 var
127 hold: double;
128 asm
129 mov edx, dword ptr[eax]
130 mov ecx, dword ptr[eax + 4]
131 bswap edx
132 bswap ecx
133 mov dword ptr [hold], ecx
134 mov dword ptr [hold + 4], edx
135 fld hold;
136 end;
137
138 procedure SwapInt64To8(const a: int64; var b: TData8);
139 asm
140 mov edx, dword ptr[a]
141 mov ecx, dword ptr[a + 4]
142 bswap edx
143 bswap ecx
144 mov dword ptr [eax], ecx
145 mov dword ptr [eax + 4], edx
146 end;
147
148 function Swap8ToInt64(var a: TData8): int64;
149 asm
150 mov edx, dword ptr[eax + 4]
151 mov eax, dword ptr[eax]
152 bswap edx
153 bswap eax
154 end;
155
156 end.
|