C / Assembly help

Soldato
Joined
7 Apr 2004
Posts
4,212
Hi,

Just trying to understand what goes on behind memory allocation in C programs, at assembly level.

I made the following example code:

Code:
void func()
{
        int var = 5;
        static int static_var = 3;
  
        printf("\t[in func] var @ %p = %d\n", &var, var);
        printf("\t[in func] static_var @ %p = %d\n", &static_var, static_var);

        var++;
        static_var++;
}

int main(void)
{
        int i;
        static int static_var = 1337;

        for(i = 0; i < 5; i++)
        {
                printf("[in main] static var @ %p = %d\n", &static_var, static_var);
                func();
        }

        return 0;
}

This outputs:

Code:
[in main] static var @ 0x8049664 = 1337
        [in func] var @ 0xbf9bb604 = 5
        [in func] static_var @ 0x8049660 = 3
[in main] static var @ 0x8049664 = 1337
        [in func] var @ 0xbf9bb604 = 5
        [in func] static_var @ 0x8049660 = 4
[in main] static var @ 0x8049664 = 1337
        [in func] var @ 0xbf9bb604 = 5
        [in func] static_var @ 0x8049660 = 5
[in main] static var @ 0x8049664 = 1337
        [in func] var @ 0xbf9bb604 = 5
        [in func] static_var @ 0x8049660 = 6
[in main] static var @ 0x8049664 = 1337
        [in func] var @ 0xbf9bb604 = 5
        [in func] static_var @ 0x8049660 = 7

Ok... Now I was expecting the static_var inside the func to have the same memory address for each call of func() which it does, but i was also expecing the int to be different address with each call of func?

Looking at the assembly for func() below, I was wondering if someone can explain how the address in the assembly generated by the compiler, relate to the addresses the variables get allocated in ram at runtime by the OS? :confused:

example: mov DWORD PTR [esp+0x4],0x8049660 so this line puts a memory address of one of the two ints, into the stack pointer + 4 bytes (size of one of the two ints).

Code:
08048374 <func>:
 8048374:       push   ebp
 8048375:       mov    ebp,esp
 8048377:       sub    esp,0x28
 804837a:       mov    DWORD PTR [ebp-0x4],0x5
 8048381:       mov    eax,DWORD PTR [ebp-0x4]
 8048384:       mov    DWORD PTR [esp+0x8],eax
 8048388:       lea    eax,[ebp-0x4]
 804838b:       mov    DWORD PTR [esp+0x4],eax
 804838f:        mov    DWORD PTR [esp],0x80484f0
 8048396:       call   80482d8 <printf@plt>
 804839b:       mov    eax,ds:0x8049660
 80483a0:       mov    DWORD PTR [esp+0x8],eax
 80483a4:       mov    DWORD PTR [esp+0x4],0x8049660
 80483ab:       08
 80483ac:       mov    DWORD PTR [esp],0x804850c
 80483b3:       call   80482d8 <printf@plt>
 80483b8:       mov    eax,DWORD PTR [ebp-0x4]
 80483bb:       add    eax,0x1
 80483be:       mov    DWORD PTR [ebp-0x4],eax
 80483c1:       mov    eax,ds:0x8049660
 80483c6:       add    eax,0x1
 80483c9:       mov    ds:0x8049660,eax
 80483ce:       leave
 80483cf:        ret

Really im just wondering if someone can explain clearly whats going on in that assembly code, (how the variables are setup) and how it relates to the memory allocation of the int and static int at runtime.


Thanks for any help,
Jack
 
08048374 <func>:

/* Function prolog */
8048374: push ebp
8048375: mov ebp,esp

ebp = esp;

8048377: sub esp,0x28

So were allocating space on the stack for 40 bytes (28 hex)..

804837a: mov DWORD PTR [ebp-0x4],0x5

Moves 0x5 into where ebp-0x4 is pointing..
0x4 = sizeof(int) = 4 bytes space... so your putting value 0x5 at that location.

So the reason your variable is always at the same location on the stack is because esp is always the same when your function is called.

On my system
Code:
(gdb) l 1
1       void func()
2       {
3               int var = 5;
4               static int static_var = 3;
5         
6               printf("\t[in func] var @ %p = %d\n", &var, var);
7               printf("\t[in func] static_var @ %p = %d\n", &static_var, static_var);
8
9               var++;
10              static_var++;
(gdb) b 1
Breakpoint 1 at 0x8048374: file test.c, line 1.
(gdb) r
Starting program: /home/alex/test 
[in main] static var @ 0x8049660 = 1337

Breakpoint 1, func () at test.c:2
2       {
(gdb) i r
eax            0x28     40
ecx            0x0      0
edx            0xb7f660d0       -1208590128
ebx            0xb7f64ff4       -1208594444
esp            0xbff6868c       0xbff6868c

You might want to read this: http://www.phiral.net/stackintro.htm
http://www.phiral.net/ldbase.htm
 
Last edited:
Back
Top Bottom