8
votes

I have a few questions about EBP, ESP and stack frame in following code.

  1. Why did we subtract 28 from esp? We have two local variables x and y in main. So why didn't we subtract 8?

  2. And don't we put values to stack from right (or top) to left (or bottom)? So why did we add 1 to [eax+8] instead of [eax+4]?


func(int a, int b, int c)
{
  return a+b+c;
}
main()
{
 int x, y=3;
 x=func(y,2,1);
}

Passing Parameters in Assembly

1
Me and my fellow - cpu, obviously ;)Aleksey Ivchenko
Looks like this was compiled with gcc -faccumulate-outgoing-args to make it avoid push, instead reserving space and using mov relative to ESP.Peter Cordes
There are no [eax+4] or [eax+8] addressing modes, and no memory-destination adds. If you want to edit that part of the question into something that makes any sense and matches the answer given, that would probably be good, if you can figure out what you were thinking 8 years ago. (Or if someone else wants to edit.)Peter Cordes

1 Answers

9
votes
  1. The stack pointer is subtracted by 28 because you need 8 bytes for your two local variables and 12 bytes for the parameters to func. The extra 8 bytes are likely due to your compiler's attempt to align main's stack to a 16-byte boundary (there's already 4 bytes on the stack for main's return address and another 4 bytes when EBP was pushed to establish the stack frame in main's first instruction). See -mpreferred-stack-boundary if you're using GCC.

  2. The parameters are being passed right-to-left. Since the stack space was already allocated for the three parameters when it was subtracted from the stack pointer, 1 is moved into the "highest" position relative to the current stack pointer (+8), 2 is moved into the middle (+4), and the value in y is moved into the stack pointer itself. This is the same as pushing 1 on the stack, pushing 2 on the stack, and then pushing y on the stack. By the last push instruction, 1 is +8 from ESP, 2 is +4 from ESP, and y is +0 from ESP. Note that inside of func, it has to add 8 to these offsets because the return address is pushed on the stack from the call instruction and func pushes EBP to establish a stack frame.

  3. Confused about which structure?