Byte Ordering

Understand endianness , detection and conversion from one form to another

What is Endianness?

Endianness or Byte ordering refers to two different ways of storing multi-byte data in memory by the processor. In the embedded world where the data memory is shared and there is some hardware writing data to this block for some other piece of hardware to consume, it becomes important to understand and agree upon the endianness.

Network and Host Byte order

Yes, same applies to over the network data transfer protocols, in case you are familiar with them. The network uses big endian format while the end device may be little or big endian – hence we have the htons() and ntohs() socket level apis made available for usage. htons refers to “host to network” while ntohs refers to “network to host”  byte order conversions.


Examples

Consider a 16-bit integer in hex format 0x1234. This is represented in a “little endian” system with lower order byte first “34”. And,is represented in a “big endian” system  with higher order byte “12” first as summarized in the table below.

Address Little endian Big endian 
0x4000 34 12
0x4001 12 34

Example 32-bit data : 0xABCD1234

Address Little endian Big endian 
0x4000 34 AB
0x4001 12 CD
0x4002 CD 12
0x4003 AB 34

Detecting  the Byte order

Now that we know what big and little endian is, let’s see how we could potentially identify the endianess of a system.

Let’s assume we have a integer variable with value set to 1 – represented on a 16-bit system as 0x0001. If the first byte is 1 (that is data at lower address) then, it a Little endian system else it is a Big endian system. To check if the system is little endian we could write the sample program below.

boolean isLittleEndian()

{

int i = 0x0001;  // 16-bit variable

char* a = (char*) &i; // size of char value is a byte (8 bits)

return (*a)?1:0; // terenary operator (condition?value_if_true value_if_false)

}

If above returns true – the system is little endian else the system is big endian.


Conversion

As I had briefly mentioned above, the socket libraries support api’s for conversions such as htons() and ntohs(). Now, let’s see how we could implement our own functions for this.

htons() is used to convert from host to network order [hton] for short variable [s] : that is little endian to big endian.

 As seen in the example below, all we have to do is swap the bytes passed. Do check the post about bit level operations to understand the trick used here.

Address Little endian Big endian 
0x4000 34 12
0x4001 12 34

uint16 htons(uint16 input)

{

//reuse the endian check function

if(isLittleEndian())

{

//host is little endian – conversion needed

//use bit manipulation tricks to swap the bytes in-place as below

return ((input&0xFF00>>8)|(input&0x00FF<<8));

}

else

{

//this means it is in big endian format

// no conversion needed

return input;

}

}


That’s all in this tidbit.

Until next tidbit, keep decoding ! Happy programming !

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: