title: Why does GCC insert seemingly non-essential instructions before a printf call?
body: <p>I'm trying to learn x86 on my own and I decided to dissect a simple c program and see what GCC outputs.  The program is this:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  int main() {
    printf("%s","Hello World");
    return 0;
  }
  </code></pre>
  
  <p>I compiled the code with -S and then stripped out things that I found unnecessary and reduced the assembly code to this.</p>
  
  <pre><code>.pfArg:
  .string "%s"
  .text
  
  .Hello:
  .string "Hello World"
  .text
  
  .globl main
  .type   main, @function
  
  main:
  pushq   %rbp        # push what was in base pointer onto stack
  movq    %rsp, %rbp  # move stack pointer to base pointer
  subq    $16, %rsp   # subtract 16 from sp and store in stack pointer
  
  # prepare arguments for printf
  movl    $.Hello, %esi   # put &amp; of "Hello World" into %esi
  movq    $.pfArg, %rdi   # put &amp; of "%d" into %eax
  call    printf
  leave
  ret
  </code></pre>
  
  <p>Now almost everything in the code above makes sense to me except the first two under main.  Although this is what I get without stripping things out.</p>
  
  <pre><code>.LC0:
      .string "%s"
  
  .LC1:
      .string "Hello World"
      .text
  
  .globl main
      .type   main, @function
  
  main:
  
  .LFB0:
      pushq   %rbp        # push what was in base pointer onto stack
      movq    %rsp, %rbp  # move stack pointer to base pointer
  
    # prepare arguments for printf
      movl    $.LC0, %eax # put arg into %eax
      movl    $.LC1, %esi # put second arg into %esi
      movq    %rax, %rdi  # move value in %rax to %rdi ???? ( why not just put $.LCO into %rax directly )
      movl    $0, %eax    # clear out %eax ???? ( why do we need to clear it out )
      call    printf      
      movl    $0, %eax    # return 0
      leave
      ret
  
  .LFE0:
      .size   main, .-main
      .ident  "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
      .section    .note.GNU-stack,"",@progbits
  </code></pre>
  
  <p>There are 2 instructions that I've marked with ???? that I don't understand.  </p>
  
  <p>The first instruction is moving what is in %rax into %rdi to prepare for the printf call. Thats all fine except we just moved $.LC0 (which is the string "%s") into %eax.  This seems unnecessary why didn't we just move $.LC0 into %rdi in the first place instead of moving it into %eax and then into %rdi?</p>
  
  <p>The second instruction is clearing out %eax which I understand to be the return value of a function.  But if the function is going to just clobber it anyways why do GCC care to clear it out?</p>