I am trying to understand the stack and frame pointer. I have the simple C program below:
#include <stdio.h>
#include <stdlib.h>
int myfunction(int counter) {
int result = 5;
printf("myfunction %p %p %p\n", &result, &counter, __builtin_frame_address(0));
return 0;
}
int main()
{
int i;
int j;
printf("main %p %p\n", &i, __builtin_frame_address(0));
myfunction(4);
return 0;
}
When I run the program using gdb and inspect the memory location starting with the address of the builtin frame I get the following output :
This is causing my confusion. I assumed the FP which has the address 0xbffff608
will point to the starting address of the stack as a result I expected that result
and counter
would have memory addresses starting higher or lower than the FP address, but this is the order of the memory addresses which are not following the assumption I had, could someone please help in clarifying this?
The memory addresses:
- 0xbffff608 (builtin frame address, I assume this is the frame pointer)
- 0xbffff610 (address of the counter argument)
- 0xbffff5f8 (address of the result variable)
What confuses me is that I thought frame pointer indicates the starting address of the stack, thus in this case 0xbffff608 points to the starting address of the current stack, then the counter and result in the current stack should all start after or before the frame pointer. But, now it is mixed. counter has a memory address higher than frame pointer while result has a memory address lower than the frame pointer. If the frame pointer indicates the start of the stack, why is then the situation?
Update: main function disassembly
CodePudding user response:
The exact use of the frame pointer is system and compiler dependent, but the observations can be explained as follows:
The difference between counter
and result
is that counter
is an argument which is pushed on the stack by the caller (main()
) while result
is a local variable belonging strictly to the function (myfunction()
).
Only result
belongs to the function frame because the function only takes responsibility for cleaning up its own local variables while arguments are cleaned up by the caller.
It makes good sense that the caller has responsibility for cleaning up arguments since the size of arguments may not be constant (e.g. printf()
).
CodePudding user response:
The order of the stack is
- paramters
- return address
- base pointer
- local variables
At < 11> you can see that ebp = esp the same will happen for myFunction. If you look at the order you notice that parameters have higher addresses. Thats why counter has higher address and result lower.