I have to preface all my comments by saying that I was still studying hard.
I will ignore section initialization. An explanation of the section initialization and basically everything that I will explain can be found here: http://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax
Ebp register is the stack stack of the base pointer, hence BP. It stores a pointer to the beginning of the current stack.
The esp register is a stack pointer. It contains a memory cell at the top of the stack. Each time we push something on the stack, esp is updated, so that it always points to the address of the top of the stack.
So ebp points to the base and esp points to the top. So the stack looks like this:
esp -----> 000a3 fa 000a4 21 000a5 66 000a6 23 esb -----> 000a7 54
If you hit e4 on the stack, this will happen:
esp -----> 000a2 e4 000a3 fa 000a4 21 000a5 66 000a6 23 esb -----> 000a7 54
Please note that the stack is growing towards lower addresses, this fact will be important below.
The first two steps are known as the prologue of the procedure or, most often, the prologue of the function , they prepare the stack for use by local variables. See the summary of the procedure below.
In step 1, we store a pointer to the old stack stack on the stack, calling pushl% ebp. Since main is the first function called, I have no idea what the previous% ebp value is.
Step 2: We introduce a new frame stack, because we introduce a new function (main). Therefore, we must set a new stack frame base pointer. We use the value in esp as the beginning of our stack frame.
Step 3. Allocates 8 bytes of space on the stack. As we mentioned above, the stack grows to lower addresses, thus, subtracting by 8, moves the top of the stack by 8 bytes.
Step 4; Select the stack, I found different opinions on this. I'm not quite sure that this is done. I suspect this is being done in order to allow large instructions (SIMDs) to stand out on the stack,
http://gcc.gnu.org/ml/gcc/2008-01/msg00282.html
This code "and" s ESP with 0xFFFF0000, aligning the stack with the next lowest 16-byte boundary. Examination of the source code of Mingw shows that this may be for SIMD instructions appearing in the "_main" routines that work only on aligned addresses. Since our procedure does not contain SIMD instructions, this line is not required.
http://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax
Steps 5 through 11 seem to have no purpose for me. I could not find any explanation on Google. Maybe someone who really knows this material provides a deeper understanding. I heard rumors that this material is used to handle C exceptions.
Step 5 stores the return value of main 0 in eax.
Step 6 and 7 for some unknown reason, add 15 to hex to eax. eax = 01111 + 01111 = 11110
Step 8 we shift the bits eax 4 bits to the right. eax = 00001, because the last bits are shifted from the end of 00001 | 111.
Step 9 shift the bits eax 4 bits to the left, eax = 10000.
Steps 10 and 11 move the value in the first 4 allocated bytes on the stack to eax, and then move it back from eax.
Steps 12 and 13 install the c library.
We have reached the epilogue function . That is, part of the function returns the stack pointers, esp and ebp to the state they were in before this function was called.
Step 14, leave the esp value equal to the ebp value, moving the top of the stack to the address that was before main was called. He then sets up ebp to indicate the address that we saved on the top of the stack in step 1.
Holidays can only be replaced with the following instructions:
mov %ebp, %esp pop %ebp
Step 15, returns and exits the function.
1. pushl %ebp 2. movl %esp, %ebp 3. subl $8, %esp 4. andl $-16, %esp 5. movl $0, %eax 6. addl $15, %eax 7. addl $15, %eax 8. shrl $4, %eax 9. sall $4, %eax 10. movl %eax, -4(%ebp) 11. movl -4(%ebp), %eax 12. call __alloca 13. call ___main 14. leave 15. ret
Prolog Procedure:
The first thing that a function needs to do is called the prolog procedure. This first saves the current base pointer (ebp) with the pushl% ebp instruction (remember that ebp is a register used to access functional parameters and local variables). Now it copies the stack pointer (esp) to the base pointer (ebp) with the instruction movl% esp,% ebp. This allows access to function parameters as indices from the base pointer. Local variables are always subtracted from ebp, for example, -4 (% ebp) or (% ebp) -4 for the first local variable, the return value is always 4 (% ebp) or (% ebp) +4, each parameter or argument is N * 4 + 4 (% ebp), for example 8 (% ebp) for the first argument while the old ebp is in (% ebp).
http://www.milw0rm.com/papers/52
There is a really great thread that answers many of these questions. Why is there more instructions in my gcc release?
A good link to x86 machine code instructions can be found here: http://programminggroundup.blogspot.com/2007/01/appendix-b-common-x86-instructions.html
This is a lecture that contains some of the ideas below: http://csc.colstate.edu/bosworth/cpsc5155/Y2006_TheFall/MySlides/CPSC5155_L23.htm
Here is another answer to your question: http://www.phiral.net/linuxasmone.htm
None of these sources explain everything.