Stack contents during a function call
I'm trying to understand what will be present on the stack during a function call.
As far as I have learnt, arguments to the callee (if any), the return address of the caller and the base address would be pushed on the stack before calling another function.
So, I wrote a simple C program
#include <stdio.h>
void
foo()
{
}
int
main()
{
foo();
return 0;
}
and the corresponding dis-assembled machine code is
08048334 <foo>:
8048334: 55 push %ebp
8048335: 89 e5 mov %esp,%ebp
8048337: c9 leave
8048338: c3 ret
08048339 <main>:
8048339: 55 push %ebp
804833a: 89 e5 mov %esp,%ebp
804833c: 83 ec 08 sub $0x8,%esp
804833f: 83 e4 f0 and $0xfffffff0,%esp
8048342: b8 00 00 00 00 mov $0x0,%eax
8048347: 83 c0 0f add $0xf,%eax
804834a: 83 c0 0f add $0xf,%eax
804834d: c1 e8 04 shr $0x4,%eax
8048350: c1 e0 04 shl $0x4,%eax
8048353: 29 c4 sub %eax,%esp
8048355: e8 da ff ff ff call 8048334 <foo>
804835a: b8 00 00 00 00 mov $0x0,%eax
804835f: c9 leave
8048360: c3 ret
8048361: 90 nop
8048362: 90 nop
8048363: 90 nop
While foo()'s code makes sense, I couldn't understand main's() code. Why is that there are so many operations? I was only expecting the following operations inside main()
1. Push the frame pointer
2. Call foo (which will inturn save the return address)
Can someone please explain me main()'s code? Thanks!
On x86 (which you might have tagged this as), the ABIs (application binary interface) demands the stack to be aligned to some boundary (16 bytes in this case) when a function is called. So when main()
wants to call foo()
, it first has to align the stack-pointer.
The first three lines of main
8048339: 55 push %ebp
804833a: 89 e5 mov %esp,%ebp
804833c: 83 ec 08 sub $0x8,%esp
are called the function prologue. This set of instructions pushes the base pointer onto the stack, then assigns the base pointer the value of the current stack thus creating a new stack frame. The stack pointer is then decreased to reserve space for the function's local variables (which you don't have but is still done due to the calling convention). The next instruction
804833f: 83 e4 f0 and $0xfffffff0,%esp
aligns the stack to the next lower 16 byte boundary. The following instructions
8048342: b8 00 00 00 00 mov $0x0,%eax
8048347: 83 c0 0f add $0xf,%eax
804834a: 83 c0 0f add $0xf,%eax
804834d: c1 e8 04 shr $0x4,%eax
8048350: c1 e0 04 shl $0x4,%eax
8048353: 29 c4 sub %eax,%esp
have appeared on SE a few times already (here, as pointed out by Paul R, and here,and again here). This routine seems to reserve additional space on the stack but does this in a strangely ineffective way. This section may depend on gcc version and OS and does not seem to be necessary.
The rest of the instructions calls foo and exits the program.
链接地址: http://www.djcxy.com/p/80374.html上一篇: 调用函数后堆叠
下一篇: 在函数调用期间堆叠内容