Byte Order ========== Version: $Id: endian.txt,v 1.3 2001/05/03 01:03:04 andrew Exp $ Some CPUs are referred to as "big-endian" while others as "little-endian". The names refer to which way bytes in multibyte numbers are stored. Take for an example the number 1. Assuming the computer uses 16bits (2 bytes) for integers we know that 1 is stored in binary as a 1 and 15 0s...the question is at which end the 1 lays... Terminology ----------- Most Significant Bit (MSB) - the bit that has the highest value in a binary number. Least Significant Bit (LSB) - the bit that has the lowest value in a binary number. Column Value: 4 2 1 ----- 1 0 0 = 4 ^ ^ MSB LSB The MSB has a value of 4, while the LSB has a value of 1. In a big endian machine the MSB is at the lowest memory address, in a little endian machine it is stored at the highest address. Example ------- Take the hex number 0x12345678. The most significant byte is 0x12. We'll assume we have 32bit (4 byte) integers. Memory Address | 0x8000 0x8001 0x8002 0x8003 ----------------+------------------------------- Big Endian | 12 34 56 78 Little Endian | 78 56 34 12 Big-endian CPUs include Sparc (as found in nias), PowerPC (as found in Macs) Motorola 68Ks (as found in a lot of embedded systems such as the one you used in Microprocessors), Hewlett Packard PA Risc and Cray Supercomputers. Numbers sent across the Internet are in big-endian byte order. Little-endian CPUs include Intel x86 and clones. Some CPUs such as the Hitachi SH3 (used in the Sony Playstation possibly) and MIPS (used in SGI machines) can do either. Why Should You Care? -------------------- Most of the time it makes very little difference to you as a programmer. Problems only occur when you take binary data from one architecture to another (such as using the provided data file on an x86 based computer). The data is in big-endian format and an Intel CPU will try and read it as little-endian...e.g. 0x00000001 (1) will be read as 0x01000000 (16777216). AS LONG AS YOU DO YOUR ASSIGNMENT ON nias YOU DON'T HAVE TO DO ANYTHING. If you want to do your assignment on an x86 based machine you will need to swap the bytes around after reading them from the file and swap them back again before writing. There are 2 functions provided for this...ntohl and htonl. ntohl converts a 32 bit number from network (big-endian) byte order to the byte order of the CPU you are now using. This means that the bytes are swapped on an x86 CPU and that nothing happens if you are running on a Sparc CPU. This "nothing happens" behaviour means it is safe to call ntohl all the time. htonl converts a 32 bit number from host byte order (the byte order of the CPU you are using now) to network (big-endian) bye order. Example ------- Assuming code is run on nias: unsigned int i; i = 1; /* i = 0x00000001 */ i = htonl(i); /* i = 0x00000001 */ i = ntohl(i); /* i = 0x00000001 */ Assuming code is run on a machine with an Intel CPU: i = 1; /* i = 0x01000000 */ i = htonl(i); /* i = 0x00000001 */ i = ntohl(i); /* i = 0x01000000 */