Byte and Bit Order Dissection

Discussing the differences between big and little endianness, bit and byte order and what it all means.

Editors' Note: This article has been updated since its original posting.

Software and hardware engineers who have to deal with byte and bit order issues know the process is like walking a maze. Though we usually come out of it, we consume a handful of our brain cells each time. This article tries to summarize the various areas in which the business of byte and bit order plays a role, including CPU, buses, devices and networking protocols. We dive into the details and hope to provide a good reference on this topic. The article also tries to suggest some guidelines and rules of thumb developed from practice.

Byte Order: the Endianness

We probably are familiar with the word endianness. First introduced by Danny Cohen in 1980, it describes the method a computer system uses to represent multi-byte integers.

Two types of endianness exist, big endian and little endian. Big endian refers to the method that stores the most significant byte of an integer at the lowest byte address. Little endian is the opposite; it refers to the method of storing the most significant byte of an integer at the highest byte address.

Bit order usually follows the same endianness as the byte order for a given computer system. That is, in a big endian system the most significant bit is stored at the lowest bit address; in a little endian system, the least significant bit is stored at the lowest bit address.

Every effort is made to avoid bit swapping in software when designing a system, because bit swapping is both expensive and tedious. Later sections describe how hardware takes care of it.

Documentation Guideline

Just as most people write a number from left to right, the layout of a multi-byte integer should flow from left to right, that is, from the most significant to the least significant byte. This is the most clear way to write integers, as we can see in the following examples.

Here is how we would write the integer 0x0a0b0c0d for both big endian and little endian systems, according to the rule above:

Write Integer for Big Endian System

byte  addr       0         1       2        3
bit  offset  01234567 01234567 01234567 01234567
     binary  00001010 00001011 00001100 00001101
        hex     0a       0b      0c        0d

Write Integer for Little Endian System

byte  addr      3         2       1        0
bit  offset  76543210 76543210 76543210 76543210
     binary  00001010 00001011 00001100 00001101
        hex     0a       0b      0c        0d

In both cases above, we can read from left to right and the number is 0x0a0b0c0d.

If we do not follow the rule, we might write the number in the following way:

byte  addr      0         1       2        3
bit  offset  01234567 01234567 01234567 01234567
     binary  10110000 00110000 11010000 01010000

As you can see, it's hard to make out what number we're trying to represent.

Simplified Computer System Used in this Article

Without losing generality, a simplified view of the computer system discussed in this article is drawn below.

CPU, local bus and internal memory/cache all are considered to be CPU, because they usually share the same endianness. Discussion of bus endianness, however, covers only external bus. The CPU register width, memory word width and bus width are assumed to be 32 bits for this article.

Endianness of CPU

The CPU endianness is the byte and bit order in which it interprets multi-byte integers from on-chip registers, local bus, in-line cache, memory and so on.

Little endian CPUs include Intel and DEC. Big endian CPUs include Motorola 680x0, Sun Sparc and IBM (e.g., PowerPC). MIPs and ARM can be configured either way.

The CPU endianness affects the CPU's instruction set. Different GNU C toolchains for compiling the C code ought to be used for CPUs of different endianness. For example, mips-linux-gcc and mipsel-linux-gcc are used to compile MIPs code for big endian and little endian, respectively.

The CPU endianness also has an impact on software programs if we need to access part of a multi-byte integer. The following program illustrates that situation. If one accesses the whole 32-bit integer, the CPU endianness is invisible to software programs.

union {
    uint32_t my_int;
    uint8_t  my_bytes[4];
} endian_tester;
endian_tester et;
et.my_int = 0x0a0b0c0d;
if(et.my_bytes[0] == 0x0a )
    printf( "I'm on a big-endian system\n" );
else
    printf( "I'm on a little-endian system\n" );
______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Memory bit order of int

Anonymous's picture

On a system with little endian and int holding 32 bits. If one want to bit twiddle and set bits by memory order, would this be correct?

* To set bit 1,2,8,29 of int my_int in memory, in c, one would set bit:

bit 1: my_int |= 1 << 7;
10000000 00000000 00000000 00000000 (0x80000000)
bit 2: my_int |= 1 << 6;
11000000 00000000 00000000 00000000 (0xc0000000)
bit 8: my_int |= 1 << 15;
11000000 10000000 00000000 00000000 (0xc0800000)
bit 29: my_int |= 1 << 26;
11000000 10000000 00000000 00000100 (0xc0800004)

If so, is there any trick to calculate the left-shift from a given value, i.e. "Set bit 29" - give 26.

As the left-shift order would be:

set  left
bit  shift
 0    7
 1    6
 2    5
 3    4
 4    3
 5    2
 6    1
 7    0
 8   15
 9   14
10   13
11   12
12   11
..   ..

have tried with various ((set_bit%BITS_PER_INT / CHAR_BIT) * CHAR_BIT) + ...; variants but always become a big huge pile of mods and so on.

Any good trick for this?

(I'm perhaps thinking wrong here, - starting to get to late)

Bit order?

Anonymous's picture

What is bit order? In which machines do bits have addresses?

Ethernet Address Endianess

Nick Collins's picture

I think your description of Ethernet Addressing is mistaken. In your example where the MAC address 12:34:56:78:9a:bc, you say that "12" will appear on the line first. This is not correct. The "bc" will appear first. Refer to section 3.2 of the 802.3 spec. It explicitly states the byte ordering of the Length field and the CRC are high-order byte first. So, I'm led to believe that the SA and DA are low-order byte first.

This would make sense because we know that the first bit on the wire determines multicast or unicast and that this is the LSB of the entire field...which is the last byte (not of the 1st byte).

Void

Nick Collins's picture

Nevermind my previous posting. It was a late night.

Errata: dot2ip() function

kingchurch's picture

It's incomplete in this on-line version which should be:

/* dot2ip - convert a dotted decimal string into an
* IP address
*/
uint32_t dot2ip(char *pdot)
{
uint32_t i,my_ip;

my_ip=0;
for (i=0; i
my_ip = my_ip*256+atoi(pdot);
if ((pdot = (char *) index(pdot, '.')) == NULL)
break;
++pdot;
}
return my_ip;
}

Re: Errata: dot2ip() function

kingchurch's picture

Already fixed by LJ, thanks!

Errata for ASCII Graphs

kingchurch's picture

Most of the ASCII graphs inlined in this on-line version of
the article are not formatted properly.

I'm contacting LJ to correct the format. In the meanwhile
you can reference my original article here if you get
confused of the ASCII graphs:

http://www.employees.org/~hek2000/articles/endianess-v0.7.html

Re: Errata for ASCII Graphs

kingchurch's picture

Already fixed. by LJ. Thanks!

Re: Byte and Bit Order Dissection

feiyunw's picture

1. A great article;
2. I suggest you create a HOWTO in the Linux Documentation Project (www.tldp.org) so that more people can benefit from your article;
3. As I know, bit0 is the MSB in Motorola PowerPC Manual; maybe you should clarify your bit numbering explicitly;

Re: Byte and Bit Order Dissection

kingchurch's picture

Thank you!
I'll consider the HOWTO suggestion.
About the 3rd comment, have you seen the "Typo"
discussion thread other readers brought up ?
Hopefully my correction to the typo can address your
doubt too.

- kevin

Typo?!

Anonymous's picture

"That is, in a big endian system the most significant bit is stored at the lowest bit address; in a little endian system, the least significant bit is stored at the lowest bit address."

Re: Typo?! -- -Yes, it's an error

kingchurch's picture

In fact, it is an error. In the original article I submitted
to LJ , I wrote:

"That is, in a big endian system, the most significant
bit is stored at the lowest bit address and in a
little endian system, the least significant bit is
stored at the lowest bit address." ---- Correct
^^^^^^
But somehow it was changed to the following
in the on-line version without notifying me.

"That is, in a big endian system, the most significant
bit is stored at the lowest bit address and in a
little endian system, the least significant bit is
stored at the highest bit address." --- Wrong
^^^^^^^^
I'm contacting LJ to correct this error now,
in the meanwhile please reference my original
sentence.

Thanks,

Kevin

Big and Little Endians

Anonymous's picture

Thank you for the pow wow concerning big endians and little endians. One thing is clear, although there are several kinds of endians, there are neither good endians nor bad endians. It would be nice to have but one type of endian, but uniting all endian tribes of thought under one teepee is not likely for the forseeable future. Nevertheless, it would be nice to hold a big council, so let me know when and where, and I'll make a reservation to attend.

Re: Typo?!

kingchurch's picture

The sentence you quoted follows "Bit order usually follows the same endianness as the byte order for a given computer system. ".

So I'm illustrating what the bit order will look like if it follows
the byte order on the same architecture. In another
word, in some systems where bit order doesn't follow
byte order, the quoted sentence is not applicable.

Thanks,

Kevin

Re: Typo?!

Anonymous's picture

No not really. What is meant is that in big-endian, bit 0 is the most significant bit and in little-endian, bit 7 is the most significant bit (for a single byte).

Example:
In most RISC architectures a 64-bit bus would be represented as 64bus

In an Intel system a 64-bit bus would be represented as 64bus

Re: Byte and Bit Order Dissection

Anonymous's picture

You left out everyone's favorite forgotten case: Middle endian! And a mention of the origin of "endian" (we have the Lilliputians to thank for this).

Seriously, though -- good article.

Re: Byte and Bit Order Dissection

kingchurch's picture

Thank you for the input. It must be more complete to include
"Middle Endian" in the discussion.
On the other hand, I have a word count limitation for the article
which forces me include only the most typical cases :p

Kevin

Re: Byte and Bit Order Dissection

Anonymous's picture

No, I was kidding about Middle Endian. It's an obsolete format (or rather, _they're_ obsolete formats). But no byte order discussion is complete without a mention of "Gulliver's Travels". Right after "First introduced by Danny Cohen in 1980, it describes the method a computer system uses to represent multi-byte integers." should be something like, "This was a reference to the disagreement about which side of an egg was the proper side to crack first."

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix