For example, in copy.c
in pset4
, how is 0x42 0x4d
(ASCII for 'BM') stored in bfType
which is of the type uint16_t
?
It can't be bfType = 0x424d
because that is a completely different number.
And of course bfType = 0x42 0x4d
won't even compile.
I need to know this because I'm trying to figure out a way to read the first 4 bytes in a buffer for recover.c
.
2 Answers
It can't be
bfType = 0x424d
because that is a completely different number.
Yes, it would surely be a different value if it was interpreted as a whole and compared it with each of the 0x42 and 0x4d separately. But what technically happens is something like this
/* imagine this is the memory */
b0 b1 b2 b4 ...
[0x42][0x4d][....][....] ...
Relying on the fact that these values are contiguous in memory and assuming we are reading from left to right:
You could read byte0 (b0) into a variable of size byte (or more) and compare it with 0x42 which is a single byte long and repeat the process with byte1 (b1), comparing it with 0x4d.
Or you could read b0 and b1 as a whole into a variable that is 2-byte long and compare them with 0x424d.
What wouldn't make sense though is reading the two bytes and comparing them against one byte or reading one byte and comparing it against two bytes.
I really don't understand it very well myself but i am going to try explain it.
It is all related to the way this values are stored in the memory, RAM, hard drives, ..., integers, decimal numbers, hexadecimal numbers, ascii characters and more, at the end all are converted to binary in order to be stored in memory, only 0's and 1's.
For example:
The ascii character 'B'
has de decimal value of 66
and to store it in memory is converted to binary and becomes 01000010
eight bits, or one byte in this case.
The same goes for hexadecimal number 0x42
that translate to 66
and 01000010
in decimal and binary respectively.
But interesting things start to happen when you try longer sequences:
Value Representation in memory
B 01000010
M 01001101
0x42 01000010
0X4D 01001101
BM 01000010 01001101
0x424D 01000010 01001101 // This is not completly true but it will give you an idea, i'll explain it later.
When you translate the binary in the memory to ascci, in this case every byte or eight bits represents a character. And for hexadecimal every byte or eight bits represents a pair of digits.
Of course if you translate 0x424D
or 01000010 01001101
to his decimal value which is 16973
it doesn't correspond to any ascii value.
So in order to represent the data stored in memery in hexadecimal form is a starndard practice to write pairs of digits, corresponding to a single byte.
And for recover.c
, to check the first four bytes of the buffer, i recomend you to look one byte at a time, otherwise is very easy to make mistakes.
EDIT:
Revising the answer just realized that i forgot to mention that due to the endianness the bytes are readed or stored backwards in the appliance, i know very little about this but i think is processor related, and may be different in other systems.
If you look at the code on copy.c, you will see this on line 54:
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
Notice that the pair of digits in the hex number 0x4d42
are backwards. This is because the appliance is a little-endian system. This is one more reason to check only one byte at a time, it is easy to do an error.
If you are interested on this topic, you can find more in the wikipedia