I'm self-studying how compilers works. I'm learning by reading the disassembly of GCC generated code from small 64-bit Linux programs.
I wrote this C program:
#include <stdio.h>
int main()
{
    for(int i=0;i<10;i++){
        int k=0;
    }
}
After using objdump I get:
00000000004004d6 <main>:
  4004d6:       55                      push   rbp
  4004d7:       48 89 e5                mov    rbp,rsp
  4004da:       c7 45 f8 00 00 00 00    mov    DWORD PTR [rbp-0x8],0x0
  4004e1:       eb 0b                   jmp    4004ee <main+0x18>
  4004e3:       c7 45 fc 00 00 00 00    mov    DWORD PTR [rbp-0x4],0x0
  4004ea:       83 45 f8 01             add    DWORD PTR [rbp-0x8],0x1
  4004ee:       83 7d f8 09             cmp    DWORD PTR [rbp-0x8],0x9
  4004f2:       7e ef                   jle    4004e3 <main+0xd>
  4004f4:       b8 00 00 00 00          mov    eax,0x0
  4004f9:       5d                      pop    rbp
  4004fa:       c3                      ret    
  4004fb:       0f 1f 44 00 00          nop    DWORD PTR [rax+rax*1+0x0]
Now I have some doubts.
- What is that NOP at the end for, and why is it there? (alignment?) 
- I'm compiling with - gcc -Wall <program.c>. Why am I not getting the warning- control reaches end of non-void function?
- Why doesn't the compiler allocate space on the stack with - sub rsp,0x10? Why doesn't it use the- rbpregister for referencing local stack data?- PS: If I call a function (like - printf) in the- forloop, why does the compiler suddenly generate- sub rsp,0x10? Why does it still references local data with the- rspregister. I expect the generated code to reference local stack data with- rbp!
 
     
     
     
     
    