title: Why does gcc push %rbx at the beginning of main?
body: <p>The latest version of gcc is producing assembly that doesn't make sense to me.  I compiled the code using no optimization; but, some parts of this code don't make sense, even with no optimization.</p>
  
  <p>Here is the C source:</p>
  
  <pre><code>  #include &lt;stdio.h&gt;
  
     int main()
     {
       int a = 1324;
       int b = 5657;
       int difference = 9876;
       int printf_answer = 2221;
  
       difference = a - b;
  
       printf_answer = printf("%d + %d = %d\n", a, b, difference);
  
       return difference;
     }
  </code></pre>
  
  <p>It produces this assembly:</p>
  
  <pre><code>    .file   "exampleIML-1b.c"
      .section    .rodata
  .LC0:
      .string "%d + %d = %d\n"
      .text
  .globl main
      .type   main, @function
  main:
  .LFB0:
      .cfi_startproc
      pushq   %rbp
      .cfi_def_cfa_offset 16
      .cfi_offset 6, -16
      movq    %rsp, %rbp
      .cfi_def_cfa_register 6
      pushq   %rbx
      subq    $24, %rsp
      movl    $1324, -32(%rbp)
      movl    $5657, -28(%rbp)
      movl    $9876, -24(%rbp)
      movl    $2221, -20(%rbp)
      movl    -28(%rbp), %eax
      movl    -32(%rbp), %edx
      movl    %edx, %ecx
      subl    %eax, %ecx
      movl    %ecx, %eax
      movl    %eax, -24(%rbp)
      movl    $.LC0, %eax
      movl    -24(%rbp), %ecx
      movl    -28(%rbp), %edx
      movl    -32(%rbp), %ebx
      .cfi_offset 3, -24
      movl    %ebx, %esi
      movq    %rax, %rdi
      movl    $0, %eax
      call    printf
      movl    %eax, -20(%rbp)
      movl    -24(%rbp), %eax
      addq    $24, %rsp
      popq    %rbx
      leave
      .cfi_def_cfa 7, 8
      ret
      .cfi_endproc
  .LFE0:
      .size   main, .-main
      .ident  "GCC: (GNU) 4.4.6 20120305 (Red Hat 4.4.6-4)"
      .section    .note.GNU-stack,"",@progbits
  </code></pre>
  
  <p>Several things don't make sense:</p>
  
  <p>(1) Why are we pushing %rbx?  What is in %rbx that needs to be saved?</p>
  
  <p>(2) Why are we moving %edx to %ecx before subtracting?  What doesn't it just do <code>sub %eax, %edx</code>?</p>
  
  <p>(3) Similarly, why the move from %ecx back to %eax before storing the value?</p>
  
  <p>(4) The compiler is putting the variable a in memory location -32(%rbp).  Unless I'm adding wrong, isn't -32(%rbp) equal to the stack pointer?  Shouldn't all local variables be stored at values <em>less than</em> the current stack pointer?</p>
  
  <p>I'm using this version of gcc:</p>
  
  <p>[eos17:~/Courses/CS451/IntelMachineLanguage]$ gcc -v
  Using built-in specs.
  Target: x86_64-redhat-linux
  Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
  Thread model: posix
  gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC) </p>