- It refers to how the bytes of our data are ordered inside the memory.
- There are two types of endianness a processor could come with (technically they are three):
- Big Endian
- Little Endian
- Biendian (From its name these types of processors could be configured as any type.)
- Note that two hex numbers are of size one byte.
Consider taking a variable of data type
int (ie. size of 4 bytes) having a value of
0x12345678 the Most Significant Bit (MSB) would be
0x1 and the Least Significant Bit (LSB) would be
0x8, similarly, the most significant byte would be
0x1234 and the least significant byte would be
Stores the most significant bytes first and then stores the least significant byte, so the most significant byte occupies the lower address of the memory while the least significant byte occupies the higher address memory.
Store the least significant byte first and then stores the most significant byte, so the least significant byte is stored in the lowest memory address while the most significant byte is stored in the higher address.
Consider the hex value of
0x01 are the address of the byte of the memory (as memory is byte-addressable).
Big Endian Little Endian +--------+ +--------+ | | | | 0x00| 0x03 | 0x00| 0xE8 | +--------+ +--------+ | | | | 0x01| 0xE8 | 0x01| 0x03 | +--------+ +--------+
Endianness is important when two computers (processors) are communicating with each other, take for an example is processor #A is little-endian while processor #B is big-endian, when processor #A sends out data it's going to send the least significant byte first and since processor #B is of big-endian it's going to interpret it as the most significant byte, thus all the data will be flipped.
Note that we will have to perform pointer downcast and the reason for that is the length modifier
%x is of integer type. Check the man pages
If we didn't do this conversion the result would be the same integer regardless of the architecture of our processor.
printf("The size of data type long long is %d.\n", sizeof(long long)); printf("The size of data type int is %d.\n", sizeof(int)); /* Assign an 8 byte value to x. */ unsigned long long x = 0x0000000000000004; /*Assign the address of variable x to x_ptr. */ unsigned long long *x_ptr = &x; /* Both x_ptr and y_ptr have the same value which is the address of variable x. What are doing here is just telling the processor is variable y_ptr is pointing at an integer, rather than the data type long long. */ unsigned int *y_ptr = (unsigned int *)x_ptr; /* Derefrence the value of y_ptr. */ unsigned int y = *y_ptr; /* Just printing out the value of y with 0s leading as padding. */ printf("The value of y is %#.8x", y);
The result will vary from one architecture to another, the value of y would be
0x00000003 if we are running a little-endian processor (which we are, since x86 processors are little-endian), and the value of y would be
0x00000000 if we were running a big-endian architecture.
Try out this code
The naming Big Endian and Little Endian comes from Jonathan Swift's satire Gulliver's Travels, in his book a big-endian refers to a person who cracks an egg from the large end and a little-endian refers to the one who cracks an egg from the little end.