Naruto Uzumaki
Naruto Uzumaki

Reputation: 998

gdb: examine stack and little endian clarification

I am studying about the memory layout of a program. I am using gdb to examine the stack in a little endian (intel x86_64) Linux (32 bit) machine. However, I am not able to understand the concept of big-endian and little-endian w.r.t this processor and gdb.

My sample program is:

1   #include<stdio.h>
2   
3   int main(int argc, char **argv) {
4       int a = 5;
5       char b[] = "ABCDEFGH";
6   
7       return 0;
8   }

                       [Code - 1]

The following sequence of instructions were executed in gdb.

(gdb) b 7
Breakpoint 1 at 0x8048434: file args.c, line 7.
(gdb) r
Breakpoint 1, main (argc=1, argv=0xbffff4f4) at args.c:7
7       return 0;

(gdb) x/20xw $esp
0xbffff410: 0x0011e0c0  0x08049ff4  0xbffff448  0xbffff4f4
0xbffff420: 0x00284324  0x00283ff4  0x08048470  0x00000005
0xbffff430: 0x4115d4a5  0x45444342  0x00484746  0x6a078d00
0xbffff440: 0x08048470  0x00000000  0xbffff4c8  0x00144bd6
0xbffff450: 0x00000002  0xbffff4f4  0xbffff500  0xb7fff858


                            [Code - 2]

Initially, I was confused whether the memory address 0xbffff430 in the stack above contains the value 0x41 or 0xa5. So I examined the stack starting from the address 0xbffff433.

(gdb) x/8xw 0xbffff433
0xbffff433: 0x44434241  0x48474645  0x078d0000  0x0484706a
0xbffff443: 0x00000008  0xfff4c800  0x144bd6bf  0x00000200

                             [code - 3]

As evident from the output above, the address 0xbffff433 contains the value 0x41. Thus, the address 0xbffff430 contains the value 0xa5. Thus we can conclude that memory addresses in gcc are displayed in the following order:-

0xbffff433: [0xbffff436][0xbffff435][0xbffff434][0xbffff433]  [0xbffff43a] [0xbffff439][0xbffff438][0xbffff437]
                D           C          B           A             H              G              F          E

However, since intel x86_64 is little-endian, from what I understand the order in which the character array is stored (MSB at smallest address) should be as follows:-

0xbffff433: [0xbffff436][0xbffff435][0xbffff434][0xbffff433]  [0xbffff43a][0xbffff439][0xbffff438][0xbffff437]
                 A           B         C           D             E           F           G           H

Q (a): Could some please explain where am I getting wrong?

Q (b): Furthermore, from [code 2] above we can see that the value for variable a is stored at the address 0xbffff42c. The value for variable a is: 0x00000005. Here also LSB is stored at the smallest memory address.

Q (c): However, the problem from Q (a) and (b) doesn't manifest when addresses are stored. For example, from code - 4 below we can check that at the address 0xbffff448 EBP (0xbffff4c8) is stored

(gdb) x/4xw $ebp
0xbffff448: 0xbffff4c8  0x00144bd6  0x00000002  0xbffff4f4

It is clearly visible that the address is stored in the following order:-

0xbffff448: [0xbffff44b][0xbffff44a][0xbffff449][0xbffff448]
                0xbf        0xff        0xf4        0xc8

Note: 1) I tried the above code on a VM of ubuntu-10.04-desktop-i386. I confirmed the endianness of my machine using the following code:

#include <stdio.h>
int main() 
{
   unsigned int i = 1;
   char *c = (char*)&i;
   if (*c)    
       printf("Little endian");
   else
       printf("Big endian");
   getchar();
   return 0;
}

2) I checked the following thread too Is GDB interpreting the memory address correctly? but I am still not able to understand the concept.

Thanks.

Upvotes: 4

Views: 2677

Answers (1)

Mark Plotnick
Mark Plotnick

Reputation: 10251

The char type in C on the x86 is 1 8-bit byte long, with an alignment of 1 byte; there is no endianness to take into account. Arrays in C on the x86 go from lower addresses to higher addresses. The w in x/xw means "print 4-byte words", which is fine for showing 32-bit integers and (on 32-bit systems) pointers, but not so great for chars or char arrays. Use x/9xb b or x/9cb b to see the first 9 elements of the char array b, displayed as bytes.

Upvotes: 4

Related Questions