I am trying to understand the assembly of this simple C program.
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
void foobar(char *a){
    char c = a[0];
}
int main(){
    int fd = open("file.txt", O_RDONLY);
        char buf1[100]="\0";
    char buf[100];
    int aa=0,b=1,c=2,d=3,f=2,g=3;
    read(fd,buf1,104);
    if(strlen(buf1) > 100){
    }else{
        strcpy(buf,buf1);
    }
    //strcpy(buf,buf1);
    foobar(buf1);
}
The disassembly of the executable using gdb which i got was foobar disassembly.
   0x000000000040067d <+0>: push   rbp
   0x000000000040067e <+1>: mov    rbp,rsp
   0x0000000000400681 <+4>: mov    QWORD PTR [rbp-0x18],rdi
   0x0000000000400685 <+8>: mov    rax,QWORD PTR [rbp-0x18]
   0x0000000000400689 <+12>:    movzx  eax,BYTE PTR [rax]
   0x000000000040068c <+15>:    mov    BYTE PTR [rbp-0x1],al
   0x000000000040068f <+18>:    pop    rbp
main disassembly just before foobar
   0x0000000000400784 <+243>:   lea    rax,[rbp-0xf0]
   0x000000000040078b <+250>:   mov    rdi,rax
   0x000000000040078e <+253>:   call   0x40067d <foobar>
   0x0000000000400793 <+258>:   mov    rbx,QWORD PTR [rbp-0x18]
   0x0000000000400797 <+262>:   xor    rbx,QWORD PTR fs:0x28
   0x00000000004007a0 <+271>:   je     0x4007a7 <main+278>
   0x0000000000400690 <+19>:    ret   
Now, i have a question regarding the disassembly of foobar
0x0000000000400681 <+4>:    mov    QWORD PTR [rbp-0x18],rdi
0x0000000000400685 <+8>:    mov    rax,QWORD PTR [rbp-0x18]
Wouldn't the instruction
mov rax, rdi
would do the work required by the above two instruction. Why using extra memory location rbp - 0x18 for rdi ? 
Is it related to pass by reference?
Edit:
Another question which i want to ask is why the foobar function is accessing something(rbp - 0x18) which is not in the frame of foobar.?
My gcc version is gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Edit: After using -O1 -O2 and -O3 optimization flag while compiling, the foobar assembly changes to
   0x0000000000400670 <+0>: repz ret 
and while using -O3 flag some of the disassembly of main is
   0x0000000000400551 <+81>:    rep stos QWORD PTR es:[rdi],rax
   0x0000000000400554 <+84>:    mov    DWORD PTR [rdi],0x0
   0x000000000040055a <+90>:    mov    cl,0x64
   0x000000000040055c <+92>:    mov    edi,r8d
   0x000000000040055f <+95>:    call   0x4004b0 <__read_chk@plt>
   0x0000000000400564 <+100>:   mov    rdx,QWORD PTR [rsp+0x68]
   0x0000000000400569 <+105>:   xor    rdx,QWORD PTR fs:0x28
   0x0000000000400572 <+114>:   jne    0x400579 <main+121>
   0x0000000000400574 <+116>:   add    rsp,0x78
   0x0000000000400578 <+120>:   ret    
   0x0000000000400579 <+121>:   call   0x4004c0 <__stack_chk_fail@plt>
I can't find any call to foobar in main .
                        
As several people commented, you should compile with some optimizations, e.g. at least with
gcc -O1(and preferablygcc -O2).If compiling with GCC specifically, I suggest to pass also
-fverbose-asmsince this emit helpful generated comments in the produced assembler file.Here is the relevant listing, compiled using GCC 5.1 on Debian/Sid/amd64, using
gcc-5 -O2 -fverbose-asm -S go.cthen look into the producedgo.sassembler file with a pager :The compiler inlined to call to
foobarand optimized its body to empty (since your source code has no observable side-effect forfoobar). Then it removed any call tofoobarsince it is useless.You might try to compile with
-fdump-tree-all. You'll get hundreds of dump files, corresponding to the many GCC optimization passes producing them.You could also customize your
gccwith MELT (a Lisp-like domain specific language to extend GCC), and you could even search some Gimple or Tree patterns using MELT's findgimple mode (a sort-ofgrepon the Gimple representations internal to GCC).