0

I'm reading in Professional Assembly Language by Richard Blum that when you enter a call you should copy the value of the ESP register to EBP, and he also provided the following template:

function_label:
    pushl %ebp
    movl %esp, %ebp
    < normal function code goes here>
    movl %ebp, %esp
    popl %ebp
    ret

I don't understand why this is necessary. When you push something inside the function, you obviously intend to pop it back, thus restoring ESP to it's original value.

So why have this template?
And what's the use of the EBP register anyway?

I'm obviously missing something, but what is it?

nrz
  • 10,435
  • 4
  • 39
  • 71
MasterMastic
  • 20,711
  • 12
  • 68
  • 90
  • This is called stack frame, it's useful for creating local variables that get destroyed after finishing from the function. –  Apr 07 '13 at 13:22
  • @Sp. Why wouldn't I pop those local variables? / Why popping wouldn't destroy them? Sorry for being a little slow. – MasterMastic Apr 07 '13 at 13:23
  • Perhaps you need to look at this answer, better explained, http://stackoverflow.com/questions/3699283/what-is-stack-frame-in-assembly#answer-3700219 –  Apr 07 '13 at 13:27
  • it makes for more readable and debuggable code, it is not required. the stack pointer setup by the stack frame remains static throughout the function, so local variables are always at the same offset relative to that stack pointer. The real stack pointer can then add and remove things to setup for other function calls. The alternative is the local variables/data changes its offset as the stack is used throughout the function, harder to read/follow/debug. but that much faster of course. – old_timer Apr 07 '13 at 13:44

1 Answers1

2

When you push something inside the function, you obviously intend to pop it back

That's just part of the reason for using stack. The far more common usage is the one that's missing from your snippet, storing local variables. The next common code you see after setting up EBP is a substraction on ESP, equivalent to the amount of space required for local variable storage. That's of course easy to balance as well, just add the same amount back at the function epilogue. It gets more difficult when the code is also using things like C99 variable length arrays or the non-standard but commonly available _alloca() function. Being able to restore ESP from EBP makes this simple.

More to the point perhaps, it is not necessary to setup the stack frame like this. Most any x86 compiler supports an optimization option called "frame pointer omission". Turned on with GCC's -fomit-frame-pointer, /Oy on MSVC. Which makes the EBP register available for general usage, that can be very helpful on x86 with its dearth of cpu registers.

That optimization has a very grave disadvantage though. Without the EBP register pointing at the start of a stack frame, it gets very difficult to perform stack walks. That matters when you need to debug your code. A stack trace can be very important to find out how your code ended up crashing. Invaluable when you get a "core dump" of a crash from your customer. So valuable that Microsoft agreed to turn off the optimization on Windows binaries to give their customers a shot at diagnosing crashes.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536