Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The difference of local variables in main and other function

I'm confused. I declare a variable in main function, and another variable in another function. But in the gdb, I find that the program visits the variable in main function by %esp register, and visits the variable in another function by %ebp register. shouldn't it all be visited by %ebp function? Or it's a hidden rule that visit by %esp register in main that I don't know?

/* source_file.c */
#include <stdio.h>

void localfunc(void)
{
    int local_in_func;
    local_in_func = 0x21;
    printf("local_in_func = %d\n", local_in_func);
}
int main(int argc, char **argv)
{
    int local_in_main;
    local_in_main = 0x97;
    printf("local_in_main = %d\n", local_in_main);
    return 0;
}

And its disassemble code below:

(gdb) disassemble main
Dump of assembler code for function main:
   0x08048407 <+0>: push   %ebp
   0x08048408 <+1>: mov    %esp,%ebp
   0x0804840a <+3>: and    $0xfffffff0,%esp    ; visit local_in_main by esp
   0x0804840d <+6>: sub    $0x20,%esp
   0x08048410 <+9>: movl   $0x97,0x1c(%esp)
   0x08048418 <+17>:    mov    $0x8048524,%eax
   0x0804841d <+22>:    mov    0x1c(%esp),%edx
   0x08048421 <+26>:    mov    %edx,0x4(%esp)
   0x08048425 <+30>:    mov    %eax,(%esp)
   0x08048428 <+33>:    call   0x8048300 <printf@plt>
   0x0804842d <+38>:    mov    $0x0,%eax
   0x08048432 <+43>:    leave  
   0x08048433 <+44>:    ret    
End of assembler dump.

(gdb) disassemble localfunc
Dump of assembler code for function localfunc:
   0x080483e4 <+0>: push   %ebp
   0x080483e5 <+1>: mov    %esp,%ebp
   0x080483e7 <+3>: sub    $0x28,%esp
   0x080483ea <+6>: movl   $0x21,-0xc(%ebp)    ; visit local_in_func by ebp
   0x080483f1 <+13>:    mov    $0x8048510,%eax
   0x080483f6 <+18>:    mov    -0xc(%ebp),%edx
   0x080483f9 <+21>:    mov    %edx,0x4(%esp)
   0x080483fd <+25>:    mov    %eax,(%esp)
   0x08048400 <+28>:    call   0x8048300 <printf@plt>
   0x08048405 <+33>:    leave  
   0x08048406 <+34>:    ret    
End of assembler dump.

My tools are:

  • OS: ubuntu 12.04

  • compile: gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

  • debug: GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04

like image 265
litao3rd Avatar asked Dec 23 '14 09:12

litao3rd


People also ask

What is the difference between global and local variables?

Inside a function or a block which is called local variables. Outside of all functions which are called global variables. In the definition of function parameters which are called formal parameters. Variables that are declared inside a function or block are called local variables.

What happens when you change a local variable in a function?

When the changes are made to local variable in a function, the changes are not reflected in the other function. Local variables can be accessed with the help of statements, inside a function in which they are declared. It is declared outside the function.

What are local variables in C++?

Variables that are declared inside a function or block are called local variables. They can be used only by statements that are inside that function or block of code. Local variables are not known to functions outside their own. The following example shows how local variables are used.

What is the difference between local variable and static variable?

In the above program, we have used one local variable or non-static variable and one static variable. The local variable can be accessed by using the object of the Demo class, whereas the static variable can be accessed using the name of the class.


1 Answers

Conventionally, %esp is the stack pointer and %ebp is the 'base' pointer which is usually set to where the stack pointer was at the start of the function.

Functions make local variables by pushing them onto the stack either with a direct push or by the logical equivalent of subtracting an offset from %esp and accessing the space between the old %esp (i.e. %ebp) and the new %esp.

This can either be done with a positive offset from %esp (such as via 0x1c(%esp) in main) or via a negative offset from %ebp (such as -0xc(%ebp) in `local_function1). There is no logical difference although compilers have many performance heuristics for choosing between multiple ways to achieve the same thing.

As your code is not optimised I would not put much weight into the choice, it may be the result of a heuristic that has some impact in other situations but I wouldn't expect it to make much difference here.

like image 130
CB Bailey Avatar answered Sep 28 '22 06:09

CB Bailey