Tuesday, April 16, 2013

Endian notes

Some details on bit and byte ordering.

Byte ordering:
----------------
Some machines use different byte ordering i.e. Little Endian and Big Endian.
Intel uses little endian and PowerPC,SPARC.. uses big endian format.
The above are applicable for bytes.

Bit ordering:
----------------
There is nothing like bit ordering (little/big endian) for bit storage in a
architectural smallest unit (i.e. 8bits). All archs use the same ordering
i.e. in the given bits (of a byte) the left most bit is always MSB and
right most bit is always LSB.

1000 0001
M       L

But there is something called bit numbering and this is arch dependent.
There are two numberings i.e. MSB 0 numbering and LSB 0 numbering. This
is just how you number your bits. Most of the little endian archs (Intel..)
uses LSB 0 convention and most of the big endian archs (PowerPC, SPARC..)
uses MSB 0 convention.

LSB 0 numbering:

7654 3210 <-- LSB 0 Numbering
1000 0001
M       L

0123 4567 <-- MSB 0 Numbering
1000 0001
M       L

Note that in both conventions LSB and MSB are same but only the numbering conventions
are different.

Where and How does bit ordering apply:
---------------------------------------
Bit ordering although doesn't apply in case of storage unit, however it matters
in case of serial transmission. In case of networking, the transmission is always
big endian i.e. it follows MSB 0 ordering. At physical layer i.e. ethernet devices
makes sure the big endian transmission is followed. So in the below example

7654 3210 <-- LSB 0 Numbering
1000 0001
M       L

MS bit (7th bit) is sent first followed by next and so on and LS bit would be the
last bit to be sent.

Bit field ordering in C bitfield struct:
----------------------------------------
This is not arch dependent rather it is compiler dependent. Note that Bitfields are not
portable as the bit packing done is completely compiler dependent.
Usual strategy followed is,
On a little endian machine: bit packing happens from right to left.

On a big endian machine: bit packing happens from left to right.


Eg:
typedef struct vlan_tci_s {
    uint8_t     pcp : 3;
    uint8_t     dei : 1;
    uint16_t    vid :12;
}  __attribute__ ((__packed__)) vlan_tci_t;

    vlan.a.ether_tci.pcp = 7;
    vlan.a.ether_tci.dei = 0;
    vlan.a.ether_tci.vid = 100;

On a little endian machine:
In this case starting from right to left, first pcp would be filled up, next dei and next vid.
Also since the the overall storage width is 16bit, compiler would fillup as below.
0000 0110 0100 0 111
0x0647

So the above value in little endian machine would be stored as
0x4706

On a big endian machine:
In this case starting from left to right, pcp would be filled up first, next dei and then at
last vid. So compiler would fillup the data as follows
111 0 0000 0110 0100
0xE064

So the above value in in big endian machine would be stored as
0xE064

No comments:

Post a Comment