Visualizing Little Endian using C++
programming·@hydr4·
0.000 HBDVisualizing Little Endian using C++
I have been doing computer programming for around 8 years now and some of the topics I always brushed away included bit-level and low-level under-the-hood concepts that are often abstracted from the programmer by high level languages such as Java and C#. Over time I realized that I did not fully understand what really happens on the "metal" when it came to topics like bit manipulation. Learning C and C++ made me realize the need to understand what happens at the low level. To help me remember what I learned and hopefully clarify to other readers, I am going to share what I learned about endianness on x86-based systems, which are [Little Endian](https://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Data/endian.html). Jumping straight into the code, I have written a very simple to understand program that will show how bits and bytes are stored in memory on an x86 system. It is very important to remember that endianness is about *bytes* not *bits* - very important point to remember. The results displayed by the program will support that. The code (along with comments should be self explanatory). I wrote the code with simplicity in mind so that even a beginner in C++ should find it easy to read. However, if anything is not clear, feel free to comment and I will reply as soon as I can. ```c++ #include <iostream> using namespace std; int main() { // Assign a value to a 32-bit so that we can view each of the four bytes // and read their addresses in memory. unsigned int i = 0x12345678; // char is 1 byte, so we will use it to read each of the 4 bytes in the // integer memory location. unsigned char* c = (unsigned char*)&i; // Show the value of the integer and the address in memory. // Take note of the address for comparing with other addresses displayed // for each of the bytes displayed below. cout << endl << "Value of i :\t0x" << hex << i << endl; cout << "Address of i :\t" << &i << endl << endl; // Show the address and value of the first byte. cout << "Address of c : \t0x" << (int)(c) << endl; cout << "Value of c[0] :\t0x" << hex << (int)(*c) << ", Address = 0x" << hex << (int)c << endl; c++; // Move to the 2nd byte cout << "Value of c[1] :\t0x" << hex << (int)(*c) << ", Address = 0x" << hex << (int)c << endl; c++; // Move to 3rd byte. cout << "Value of c[2] :\t0x" << hex << (int)(*c) << ", Address = 0x" << hex << (int)c << endl; c++; // Move 4th (last) byte. cout << "Value of c[3] :\t0x" << hex << (int)(*c) << ", Address = 0x" << hex << (int)c << endl; return 0; } ``` Running the program on my computer will show the following results: ``` Value of i : 0x12345678 Address of i : 0x6afee8 Address of c : 0x6afee8 Value of c[0] : 0x78, Address = 0x6afee8 Value of c[1] : 0x56, Address = 0x6afee9 Value of c[2] : 0x34, Address = 0x6afeea Value of c[3] : 0x12, Address = 0x6afeeb ``` ## Analysis What is important to take from the results is the following: 1. The least significant byte (LSB) of the integer is stored in a low memory address. This is what is expected since the system is little endian. The LSB is the one with value ```0x78```. 1. In each of the bytes, the bit order is not changed i.e., the high byte has the value ```0x12``` not ```0x21``` I have included a diagram below to show a visual representation if the bytes in memory, with low addresses at the bottom: ``` <<value>> <<adddress>> + + + + +----------+ + 12 + 0x6afeeb +----------+ + 34 + 0x6afeea +----------+ + 56 + 0x6afee9 +----------+ + 78 + 0x6afee8 +----------+ + + + + ``` That's it for this post. :)