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.
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.
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.
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|
uint16 htons(uint16 input)
//reuse the endian check function
//host is little endian – conversion needed
//use bit manipulation tricks to swap the bytes in-place as below
//this means it is in big endian format
// no conversion needed
That’s all in this tidbit.
Until next tidbit, keep decoding ! Happy programming !