When I'm building programs in my IDE, I'm building in x86 debug mode. Yes, x86 means little endianess. Little endianess means LSB byte of the data is stored at lower address.
Let's look into an C++ example, how to display the addresses and values.
uint32_t data = 0xDEADBEEF;This is the value we are going investigate how it's represented in memory. The LSB byte is
EF
and since
we are dealing with x86, it will be stored at lower address.
First we need a function to output the content of each memory address.
void DisplayMemory(uint32_t data) { auto address = reinterpret_cast<uint8_t*>(&data); auto n = sizeof(data); for (std::size_t i = 0; i < n; i++) { std::cout << "[" << static_cast<void*>(address + i) << "]: " << std::setw(2) << std::setfill('0') << std::hex << static_cast<uint32_t>(*(address + i)) << std::endl; } }Let's discuss the snippet above in more detail.
auto address = reinterpret_cast<uint8_t*>(&data);Above, we cast the address of data from
uint32_t
pointer to uint8_t
pointer and store it in an address pointer. We have to do this cast, so we can step the address pointer byte by byte. Since those types are unrelated, we have to use the reinterpret_cast
operator (and not static_cast
) for this purpose.
We could use (uint8_t*)
for conversion as well. Let's continue with the display part of the code.
std::cout << "[" << static_cast<void*>(address + i) << "]: " << std::setw(2) << std::setfill('0') << std::hex << static_cast<uint32_t>(*(address + i)) << std::endl;Above, we cast
address + i
, i.e. the uint8_t
pointer to void
pointer. Why?
If we pass uint8_t
pointer to the operator<<
, it will handle the pointer as a string (char*
).
Since we want to display the address as a hexadecimal address, we must use the static_cast
operator and cast to void
pointer for this purpose.
It is sufficient with the static_cast
operator, since all types of pointers can be converted to void
pointers (reinterpret_cast
not needed).
There is one more
static_cast
above. It is needed to display the content of the address pointer. Like the previously cast, we need static_cast
since we don't want to display a character, but a number. As a matter of fact, integer promotion could have solved this as well.
+(*(address + i))The for-loop call std::cout for each address pointer and display the associated byte value.
Note that we could have used printf as well in this example.
printf("[%x]: %.2x\n", address + i, *(address + i));Let's find out how the output from this code below, look like.
DisplayMemory(data);
0xDEADBEEF - Little endianess |
Above, we see the little endianess representation of
Now, let's continue with big endianess. Big endianess means MSB byte of the data is stored at lower address. In our example, the MSB byte is
First we need a function to convert from little endianess to big endianess.
0xDEADBEEF
. LSB byte ef
is stored at lower address.
Now, let's continue with big endianess. Big endianess means MSB byte of the data is stored at lower address. In our example, the MSB byte is
DE
, it will be stored at lower address, which we will se below.
First we need a function to convert from little endianess to big endianess.
uint32_t SwapEndians(uint32_t data) { return (data >> 24) | ((data & 0x00FF0000) >> 8) | ((data & 0x0000FF00) << 8) | (data << 24); }The implementation above uses shift and binary manipulations. Another implementation would be to copy the bytes in wanted order.
uint32_t SwapEndians(uint32_t data) { uint32_t result; uint8_t *resultPtr = reinterpret_castNow, let's use this function to display the big endian representation of(&result); uint8_t *dataPtr = reinterpret_cast (&data); resultPtr[0] = dataPtr[3]; resultPtr[1] = dataPtr[2]; resultPtr[2] = dataPtr[1]; resultPtr[3] = dataPtr[0]; return result; }
0xDEADBEEF
.
uint32_t data = 0xDEADBEEF; auto b = SwapEndians(data); DisplayMemory(b);
0xDEADBEEF - Big endianess |
Above, we see the big endianess representation of
You are welcome to leave comments, complaints or questions!
0xDEADBEEF
. MSB byte be
is stored at lower address.
You are welcome to leave comments, complaints or questions!