The difference of local variables in the main and other functions

I'm confused. I declare a variable in the main function and another variable in another function. But in gdb, I found that the program visits the variable in the main function of the %esp register and visits the variable in another function using the %ebp . shouldn't this be visited by the %ebp function? Or is this hidden rule that %esp attends registered in main , which 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 disassembly code is 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:

  • 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

+5
source share
1 answer

Typically, %esp is the stack pointer, and %ebp is the "base" pointer, which is usually set so that the stack pointer is at the beginning of the function.

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

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

Since your code is not optimized, I would not attach much importance to the choice, this may be the result of a heuristic that has some influence in other situations, but I would not expect this to make a big difference here.

+5
source

Source: https://habr.com/ru/post/1209759/


All Articles