Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Converting Big-endian to Little-endian and back?

284 views
Skip to first unread message

Bo Berglund

unread,
Mar 26, 2008, 7:38:36 PM3/26/08
to
I have data files containing records with data of various types
created on a computer system running a Motorola processor and thus the
data are stored msb first.

I want to read these on a PC, which uses an lsb first storage system.

For Word data I can use Swap(), but not for Integers, Cardinals and
single precision floats that are 32 bit and certainly not for doubles
that are 64 bit size.

So I need a swap32 and a swap64 function or procedure that can handle
values of these sizes. I have googled a few but they are special cases
in that they swap integers OR cardinals OR something else, whereas I
would like to have a general type of function where I can use any
4-byte argument type to swap 32, etc.

Is there any such function available somewhere?
And it does not hurt if it is fast too, because there are many values
to convert.


/BoB

Rob Kennedy

unread,
Mar 26, 2008, 10:33:47 PM3/26/08
to
Bo Berglund wrote:
> I have data files containing records with data of various types
> created on a computer system running a Motorola processor and thus the
> data are stored msb first.
>
> I want to read these on a PC, which uses an lsb first storage system.
>
> For Word data I can use Swap(), but not for Integers, Cardinals and
> single precision floats that are 32 bit and certainly not for doubles
> that are 64 bit size.

Note there's no guarantee that Integer and Cardinal are 32 bits. On a
64-bit version of Delphi, they'll likely be 64 bits. If you must have a
32-bit type, use LongInt or LongWord.

> So I need a swap32 and a swap64 function or procedure that can handle
> values of these sizes. I have googled a few but they are special cases
> in that they swap integers OR cardinals OR something else, whereas I
> would like to have a general type of function where I can use any
> 4-byte argument type to swap 32, etc.
>
> Is there any such function available somewhere?
> And it does not hurt if it is fast too, because there are many values
> to convert.

To do it type-safely, you need to have separate functions for each type
you want to be able to swap. The function bodies can all be identical to
the one below.

If you don't care about type safety, write a single function that takes
an untyped var parameter:

procedure Swap32(var X);
asm
mov ecx, [eax]
bswap ecx
mov [eax], ecx
end;

Just make sure you never call it on anything that isn't four bytes. The
compiler won't stop you.

--
Rob

Bo Berglund

unread,
Mar 27, 2008, 2:07:40 AM3/27/08
to
On Wed, 26 Mar 2008 21:33:47 -0500, Rob Kennedy <m...@privacy.net>
wrote:

Ok, thanks.
What happens if I use the swap32 above with a 64 bit value?
Will half of the variable be swapped only? In that case which end?
/Bo


/BoB

John Herbster

unread,
Mar 27, 2008, 6:43:39 AM3/27/08
to
"Bo Berglund" <bo.be...@telia.com> wrote

> What happens if I use the swap32 above with a 64 bit value?
> Will half of the variable be swapped only? In that case which end?

Bo,
To help get you educated in the endian area, can you find a local programmer to hire for an hour that knows about bits and bytes?
Rgds, JohnH

Rob Kennedy

unread,
Mar 27, 2008, 9:05:22 AM3/27/08
to

Nothing useful. Likewise if you call it on a 16-bit variable.

Like I said, the compiler won't stop you from trying. If you're afraid
you're going to do it accidentally, then do as I suggested and write a
type-specific function for each of the types you want to support. It's
probably a pretty short list, and you can do most of the work copy and
paste. Copy the function above, and simply give X a type. (Then use the
"overload" directive.)

Having a separate function for each type is no slower at run time.

> Will half of the variable be swapped only? In that case which end?

I don't know. You're welcome to try it and find out, though.

--
Rob

Rudy Velthuis [TeamB]

unread,
Mar 27, 2008, 9:31:04 AM3/27/08
to
Bo Berglund wrote:

> What happens if I use the swap32 above with a 64 bit value?
> Will half of the variable be swapped only? In that case which end?

The 32 bits (4 bytes) that are at the address given. Since Delphi runs
on little endian processors, that means the lower 32 bits.

Untyped var parameters are in fact just untyped references, i.e.
untyped pointers with slightly different semantics.

More here:

http://rvelthuis.de/articles/articles-pointers.html#references

--
Rudy Velthuis [TeamB] http://www.teamb.com

"All things are possible, except skiing through a revolving door."

Rudy Velthuis [TeamB]

unread,
Mar 27, 2008, 9:34:58 AM3/27/08
to
Rob Kennedy wrote:

> Note there's no guarantee that Integer and Cardinal are 32 bits. On a
> 64-bit version of Delphi, they'll likely be 64 bits.

No, they won't. This was confirmed by Allen Bauer in non-tech. Windows
won't generally use 64 bit integers or cardinals either, of course with
the exception of things like memory sizes (size_t), file sizes, etc. In
MS languages, integers (signed or unsigned) will also remain 32 bit.


--
Rudy Velthuis [TeamB] http://www.teamb.com

"The surest way to corrupt a youth is to instruct him to hold in
higher esteem those who think alike than those who think
differently" -- Friedrich Nietzsche

quick

unread,
Mar 28, 2008, 10:14:04 AM3/28/08
to
Here's one for 64bit

function Swap64(const Value: Int64): Int64;
asm
mov edx,dword ptr [Value]
mov eax,dword ptr [Value+4]
bswap eax
bswap edx
end;

0 new messages