10

Why if i check with the xxd an image eg. small.bmp the bfType is 0x424d and when you run copy in GDB the value of bf.bfType is 19778 and the program "copy" in line 55 check with 0x4d42. Is it reading it reverse order.

2
  • I assume you meant peek instead of xxd :)
    – kzidane
    Commented Aug 2, 2014 at 6:44
  • I don't think so.
    – curiouskiwi
    Commented Aug 2, 2014 at 8:35

1 Answer 1

18

bfType is an unsigned 16 bit integer (ie, 2 bytes long, aka a WORD).

What you are seeing is the fact that xxd displays byte by byte, but gdb displays the word.

So why does it matter?

Intel processors use what is called "little endian" to store bytes in memory. That means that the least significant byte is stored in the first memory address in the word.

So gdb is showing you the decimal value 19778 (even though, in reality, bfType is 2 chars (B and M) and not an integer). If you convert to hex (which I think you've done) it is 0x4D42. That is the value that copy.c is testing against.

The value 0x4D42 in a little endian system will be stored in byte order as 424D (how xxd is showing you).

One way to think about little endian is to think of a decimal number.

If you write 123, the least significant number is 3 and it is at the end, so our number system of writing is "big endian", the opposite of what our computers use.

If our number system was "little endian", then we would write "one hundred twenty three" as 321.

The entry for Endianness on Wikipedia can explain it much more detail.

But let's look at an example from the class. If you take small.bmp that is given and run xxd to see the individual bytes, you'll get this. I've added spaces between some bytes to make it clearer:

424d 5a000000 00000000 36000000 28000000 03000000
fdffffff 0100 1800 00000000 24000000 120b0000 120b0000
00000000 00000000 

00ff00 00ff00 00ff00 00 00 00
00ff00 ffffff 00ff00 00 00 00
00ff00 00ff00 00ff00 00 00 00               

So you've got a printout of the bytes of the file. What do they mean? This is where you use the bmp.h file to get the structure. Recall from the typedef's that a WORD is a unsigned 16 bit (ie, 2 byte) integer, a DWORD is an unsigned 32 bit (4 byte) integer and a LONG is a signed 32 bit (4 byte) integer. So we can then just count the bytes as we go along and assign them to their values.

Remember that the bytes are stored in little-endian fashion, with least significant byte stored first, so to calculate the decimal value, we need to think of them in the opposite order.

BITMAPFILEHEADER:           Bytes:          Hex = Decimal value:
    WORD   bfType;          42 4d           0x4d42 = 19778            
    DWORD  bfSize;          5a 00 00 00     0x0000005a = 90
    WORD   bfReserved1;     00 00           0x0000 = 0
    WORD   bfReserved2;     00 00           0x0000 = 0
    DWORD  bfOffBits;       36 00 00 00     0x00000036 = 54

BITMAPINFOHEADER:
    DWORD  biSize;          28 00 00 00     0x00000028 = 40
    LONG   biWidth;         03 00 00 00     0x00000003 = 3 
    LONG   biHeight;        fd ff ff ff     0xfffffffd = -3 
    WORD   biPlanes;        01 00           0x0001 = 1 
    WORD   biBitCount;      18 00           0x0018 = 24
    DWORD  biCompression;   00 00 00 00     0x00000000 = 0
    DWORD  biSizeImage;     24 00 00 00     0x00000024 = 36 
    LONG   biXPelsPerMeter; 12 0b 00 00     0x00000b12 = 2834 
    LONG   biYPelsPerMeter; 12 0b 00 00     0x00000b12 = 2834 
    DWORD  biClrUsed;       00 00 00 00     0x00000000 = 0 
    DWORD  biClrImportant;  00 00 00 00     0x00000000 = 0

RGBTRIPLE:
    BYTE  rgbtBlue;         00              0x00 = 0
    BYTE  rgbtGreen;        ff              0xff = 255
    BYTE  rgbtRed;          00  etc...      0x00 = 0

Those values in the last column should match what you see if you use the peek program to look at the headers of small.bmp.

Hope that helps, Brenda.

4
  • 1
    Wow, you blow up my mind. I haven't heard before about endians. The thing now is that the rest of the vars seams to be read with GDB right,. The same with xxd bfType is BM and the rest is reverse written. So i guess that the convention of starting with BM refers to the disc, and i will find it always reverse in GDB?
    – dizcola
    Commented Aug 2, 2014 at 19:20
  • I've updated my answer to give an example.
    – curiouskiwi
    Commented Aug 3, 2014 at 2:57
  • Thanks for the detailed answer. It was also the exact answer to my question.
    – BcK
    Commented Mar 29, 2017 at 22:22
  • Thanks for the big and little endian explanation! Now I get it!
    – legalbot
    Commented Jul 23, 2019 at 21:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .