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.