Assembly: Memory address of variables in C Programming
Asked Answered
Q

1

5

This is my C code

C:\Codes>gdb test -q
Reading symbols from C:\Codes\test.exe...done.
(gdb) list 1,15
1       #include<stdio.h>
2
3       int main()
4       {
5               int a = 12345;
6               int b = 0x12345;
7               printf("+-----+-------+---------+----------+\n");
8               printf("| Var | Dec   | Hex     | Address  |\n");
9               printf("+-----+-------+---------+----------+\n");
10              printf("|  a  | %d | 0x%x  | %p |\n",a,a,&a);
11              printf("|  b  | %d | 0x%x | %p |\n",b,b,&b);
12              printf("+-----+-------+---------+----------+\n");
13
14              return 0;
15      }
(gdb) set disassembly-flavor intel

And this is the standard output

C:\Codes>test
+-----+-------+---------+----------+
| Var | Dec   | Hex     | Address  |
+-----+-------+---------+----------+
|  a  | 12345 | 0x3039  | 0022FF4C |
|  b  | 74565 | 0x12345 | 0022FF48 |
+-----+-------+---------+----------+

This is what I'm seeing in GDB

(gdb) break 7
Breakpoint 1 at 0x40135e: file test.c, line 7.
(gdb) run
Starting program: C:\Codes/test.exe
[New Thread 4044.0xab0]

Breakpoint 1, main () at test.c:7
7               printf("+-----+-------+---------+----------+\n");
(gdb) disassemble
Dump of assembler code for function main:
   0x00401340 <+0>:     push   ebp
   0x00401341 <+1>:     mov    ebp,esp
   0x00401343 <+3>:     and    esp,0xfffffff0
   0x00401346 <+6>:     sub    esp,0x20
   0x00401349 <+9>:     call   0x401990 <__main>
   0x0040134e <+14>:    mov    DWORD PTR [esp+0x1c],0x3039
   0x00401356 <+22>:    mov    DWORD PTR [esp+0x18],0x12345
=> 0x0040135e <+30>:    mov    DWORD PTR [esp],0x403024
   0x00401365 <+37>:    call   0x401c00 <puts>
   0x0040136a <+42>:    mov    DWORD PTR [esp],0x40304c
   0x00401371 <+49>:    call   0x401c00 <puts>
   0x00401376 <+54>:    mov    DWORD PTR [esp],0x403024
   0x0040137d <+61>:    call   0x401c00 <puts>
   0x00401382 <+66>:    mov    edx,DWORD PTR [esp+0x1c]
   0x00401386 <+70>:    mov    eax,DWORD PTR [esp+0x1c]
   0x0040138a <+74>:    lea    ecx,[esp+0x1c]
   0x0040138e <+78>:    mov    DWORD PTR [esp+0xc],ecx
   0x00401392 <+82>:    mov    DWORD PTR [esp+0x8],edx
   0x00401396 <+86>:    mov    DWORD PTR [esp+0x4],eax
   0x0040139a <+90>:    mov    DWORD PTR [esp],0x403071
   0x004013a1 <+97>:    call   0x401c08 <printf>
   0x004013a6 <+102>:   mov    edx,DWORD PTR [esp+0x18]
   0x004013aa <+106>:   mov    eax,DWORD PTR [esp+0x18]
   0x004013ae <+110>:   lea    ecx,[esp+0x18]
   0x004013b2 <+114>:   mov    DWORD PTR [esp+0xc],ecx
   0x004013b6 <+118>:   mov    DWORD PTR [esp+0x8],edx
   0x004013ba <+122>:   mov    DWORD PTR [esp+0x4],eax
   0x004013be <+126>:   mov    DWORD PTR [esp],0x40308c
   0x004013c5 <+133>:   call   0x401c08 <printf>
   0x004013ca <+138>:   mov    DWORD PTR [esp],0x403024
   0x004013d1 <+145>:   call   0x401c00 <puts>
   0x004013d6 <+150>:   mov    eax,0x0
   0x004013db <+155>:   leave
   0x004013dc <+156>:   ret
End of assembler dump.
(gdb)

The address for variables a & b is supposed to be at 0x22ff4c & 0x22ff48 respectively

(gdb) print &a
$1 = (int *) 0x22ff4c

(gdb) print &b
$2 = (int *) 0x22ff48

However, if you look at the following GDB disassemble output, the address was not 0x22ff4c & 0x22ff48, but 0x0040134e & 0x00401356

   0x0040134e <+14>:    mov    DWORD PTR [esp+0x1c],0x3039
   0x00401356 <+22>:    mov    DWORD PTR [esp+0x18],0x12345

I've also debug this on x32dbg but getting the same address too. x32dbg

I'm confused here. What was the 0x0040134e & 0x00401356 if they are not the memory addresses for variables a & b?

Quintinquintina answered 2/7, 2017 at 3:15 Comment(0)
L
8
0x0040134e <+14>:    mov    DWORD PTR [esp+0x1c],0x3039
0x00401356 <+22>:    mov    DWORD PTR [esp+0x18],0x12345

No, 0x0040134e and 0x00401356 are not addresses for variables a and b. Instead they are address of the instruction in code, i.e. instruction pointer IP. a and b are initialized in these lines:

0x0040134e <+14>:    mov    DWORD PTR [esp+0x1c],0x3039
0x00401356 <+22>:    mov    DWORD PTR [esp+0x18],0x12345

Here the address of a and b are esp+0x1c and esp+0x18 respectively where esp is the stack pointer. As address you are getting 0x22ff4c and 0x22ff48 from which you can easily deduct that current esp is 0x22ff4c - 0x1c.

Please note the this answer ignores the underlying virtual memory management or other related memory management matters of operating system, i.e. on most architecture 0x22ff4c and 0x22ff48 will be virtual memory address, not the real physical address of your RAM.

Lelia answered 2/7, 2017 at 3:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.