1

I'm trying to explore the debugging of an assembly code (x86, 32bit, C source code).

I would like to understand how can I calculate the actual size of the stack frame of particular function in my assembly code, while using the gdb.

Is the size of the frame, the absolute difference between the %esp and %ebp, summed with every value that affects on the %esp, before everything is poped up?

pushl   %ebp
movl    %esp, %ebp
subl    $24, %esp
subl    $48, 8(%ebp)

Software: GNU gdb (Debian 7.12-6) 7.12.0.20161007-git

gcc -m32 -fno-asynchronous-unwind-tables -fno-pic -S main.c
gcc -c -m32 main.s -o main.out
gcc -g -m32 main.s -o main.out
gcc -m32 -g -o main main.s
as -a main.s

I would be thankful, if someone can help me.

U880D
  • 8,601
  • 6
  • 24
  • 40
zzoorrii
  • 11
  • 2
  • `ebp` is pretty much irrelevant (optimized code doesn't even use it). It's the difference between `esp` on entry and its lowest value in the function. – Jester May 09 '18 at 11:09

2 Answers2

0

No you can't.

A stack frame extends from the point where the first parameter is pushed onto the stack up to the last modification of the stack due to any action or instruction. I.e. allocating space for a dynamic variable using alloca() or pushing a register, or simply storing a register in preallocated stack position.

Actual compiler technology is so advanced that even the standard functions prologues and epilogues can be modified for the most aggressive optimization, making even more complex the frame unwinding.

Acting only on the base frame, that in the case of a 32bits X86 code corresponds to the value stored in the %ebp register, isn't enough.

Most recent evolution, as also @Jester said, demonstrated that even %ebp isn't necessary for exceptions stack unwind, and aggressive optimization switches in compilers, as -fomit-frame-pointer in GCC, doesn't save it on stack anymore (see libunwind below).

To access the previous frame, starting from the base frame address hold in %ebp, you need the stack width of the stack frame for the relative function, inclusive of all stack operations.

This information is normally stored in a specific section of the executable, generally using a list of records about stack operations. The sections are:

  1. .pdata for Microsoft PE executables
  2. .eh_frame and .eh_frame_hdr for ELF format (Linux).

Depending on which OS you want to work on you can get more info starting from https://www-user.tu-chemnitz.de/~heha/viewchm.php/hs/Win32SEH.chm/Win32SEH.htm for Microsoft executables.

For Linux based system you can start to look here https://gnu.wildebeest.org/blog/mjw/2007/08/23/stack-unwinding/ and eventually have an in deep reading about the DWARF debugger http://wiki.dwarfstd.org/index.php?title=Special:SpecialPages, and the https://www.nongnu.org/libunwind/ for a technically detailed immersion.

Frankie_C
  • 4,764
  • 1
  • 13
  • 30
0

In an ideal world, the local variables will be located with a constant offset from the EBP, so you could figure out the size of the stack frame. However, the compiler and optimisations are too important, and one of the scenarios could be that EBP is used as GPR (Trying to understand gcc option -fomit-frame-pointer). Could be a static analysis a nice solution?

Jose
  • 3,306
  • 1
  • 17
  • 22