Byte Swapping

Before exploring various methods of converting data, let us first examine the method most often needed: The endian conversion! The handling of big- and little-endian was initially discussed in Chapter 3 but let us re-examine.

If your application is designed to be multiplatform , then having multiple endian declarations might make your life easier. Having Endian16(), Endian32(), Endian64(), and Endian128() conversion functions are one thing, but having extra declarations such as BigEndian64() versus LittleEndian64() that map to either a stub macro or an Endian64 converter will save you some time. The data file being read will be in a known endian orientation. The target platform knows what it needs, so if the big-endian label is used if the source data is known to be big-endian and vice versa for little-endian, then the use of that declaration will resolve any confusion. This will work for any platform!

Table 6-1: Correlation between little- and big-endian orientation and whether a byte swap or a stub function is implemented

Source Data

Big-Endian Machine

Little-Endian Machine



Byte swap


Byte swap


These endian wrappers are shown only for little-endian as this book is mostly meant for little-endian. If you are truly interested, my Vector Game Math Processors book contains both sets.


Use descriptive big- versus little-endian macros to simplify endian conversion.



This is oversimplifying it and there are better methods such as the BSWAP instruction on the 80x86, but this is a generic method for cross-platform portability.

Listing 6-1: Generic 32-bit endian conversion
image from book
 int32 VMP_ENDIAN32(int32 val) {   uint8 buf[4];       buf[ 0 ]=*(((uint8*)&val)+3);   // = [3]   buf[ 1 ]=*(((uint8*)&val)+2);   // = [2]   buf[ 2 ]=*(((uint8*)&val)+1);   // = [1]   buf[ 3 ]=*(((uint8*)&val)+0);   // = [0]   return *(int32*)buf; } 
image from book
Listing 6-2: Generic 16-bit endian conversion
image from book
 int16 VMP_ENDIAN16(int16 val) {   uint8 buf[2];       buf[ 0 ]=*(((uint8*)&val)+1);   // = [1]   buf[ 1 ]=*(((uint8*)&val)+0);   // = [0]   return *(int16*)buf; } 
image from book

The typecasting camouflages it a bit, but it is merely a byte read-write with inverse offsets. I will leave the actual endian implementation up to you! Just remember that it is preferable to have the tools handle your endian conversion so that a game application does not have to. And since tools exercise the same data over and over for the length of a project, you might as well make them as efficient as possible.

For cross-platform compatibility I refer to the following as a little pretzel logic. It looks a little twisted, but if you dig a little deeper it becomes what it is slicker 'n snail snot!

(Big/Little)-Endian to (Big/Little)-Endian Data Relationship Macros

Listing 6-3: KariType.h
image from book
 #ifdef VMP_LITTLE_ENDIAN   // Little-endian processor          // Big-endian data on little-endian processor      #define VMP_BIG_ENDIAN32    VMP_ENDIAN32      #define VMP_BIG_ENDIAN16    VMP_ENDIAN16              // Little-endian data on little-endian processor      #define VMP_LITTLE_ENDIAN32                     // stub      #define VMP_LITTLE_ENDIAN16                     // stub     #endif 
image from book

Note that same endian to same endian assignment merely stubs out the macro, so no conversion is needed or implemented. One only needs to know what byte order the data is in and what order is needed, and use the appropriate macro. It will then be cross-platform compatible to all other platforms as long as the endian flag is set properly for that platform.

Neat, huh? No extra #ifdef cluttering up the code!

BSWAP Byte Swap

BSWAP destination













32.64-Bit 80X86 Assembly Language Architecture
32/64-Bit 80x86 Assembly Language Architecture
ISBN: 1598220020
EAN: 2147483647
Year: 2003
Pages: 191

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: