title: GCC Assembly Optimizations - Why are these equivalent?
body: <p>I am trying to learn how assembly works at an elementary level and so I have been playing with the <code>-S</code> output of gcc compilations.  I wrote a simple program that defines two bytes and returns their sum.  The entire program follows:</p>
  <pre><code>int main(void) {
    char A = 5;
    char B = 10;
    return A + B;
  }
  </code></pre>
  <p>When I compile this with no optimizations using:</p>
  <pre><code>gcc -O0 -S -c test.c
  </code></pre>
  <p>I get test.s that looks like the following:</p>
  <pre><code>    .file   &quot;test.c&quot;
      .def    ___main;    .scl    2;  .type   32; .endef
      .text
      .globl  _main
      .def    _main;  .scl    2;  .type   32; .endef
  _main:
  LFB0:
      .cfi_startproc
      pushl   %ebp
      .cfi_def_cfa_offset 8
      .cfi_offset 5, -8
      movl    %esp, %ebp
      .cfi_def_cfa_register 5
      andl    $-16, %esp
      subl    $16, %esp
      call    ___main
      movb    $5, 15(%esp)
      movb    $10, 14(%esp)
      movsbl  15(%esp), %edx
      movsbl  14(%esp), %eax
      addl    %edx, %eax
      leave
      .cfi_restore 5
      .cfi_def_cfa 4, 4
      ret
      .cfi_endproc
  LFE0:
      .ident  &quot;GCC: (GNU) 4.9.2&quot;
  </code></pre>
  <p>Now, recognizing that this program can very easily be simplified to just return a constant (15) I have been able to reduce the assembly by hand to perform the same function using this code:</p>
  <pre><code>.global _main
  _main:
      movl    $15, %eax
      ret
  </code></pre>
  <p>This appears to me to be the least amount of code possible (but I realize could be quite wrong) to perform this admittedly trivial task.  Is this form the most &quot;optimized&quot; version of my C program?</p>
  <p><strong>Why is the initial output of GCC so much more verbose?  What do the lines spanning from <code>.cfi_startproc</code> to <code>call __main</code> even do?  What does <code>call __main</code> do?  I cannot figure what the two subtraction operations are for.</strong></p>
  <p>Even with optimizations in GCC set to <code>-O3</code> I get this:</p>
  <pre><code>    .file   &quot;test.c&quot;
      .def    ___main;    .scl    2;  .type   32; .endef
      .section    .text.unlikely,&quot;x&quot;
  LCOLDB0:
      .section    .text.startup,&quot;x&quot;
  LHOTB0:
      .p2align 4,,15
      .globl  _main
      .def    _main;  .scl    2;  .type   32; .endef
  _main:
  LFB0:
      .cfi_startproc
      pushl   %ebp
      .cfi_def_cfa_offset 8
      .cfi_offset 5, -8
      movl    %esp, %ebp
      .cfi_def_cfa_register 5
      andl    $-16, %esp
      call    ___main
      movl    $15, %eax
      leave
      .cfi_restore 5
      .cfi_def_cfa 4, 4
      ret
      .cfi_endproc
  LFE0:
      .section    .text.unlikely,&quot;x&quot;
  LCOLDE0:
      .section    .text.startup,&quot;x&quot;
  LHOTE0:
      .ident  &quot;GCC: (GNU) 4.9.2&quot;
  </code></pre>
  <p>Which seems to have removed a number of operations, but still leaves all the lines leading to <code>call __main</code> that seems unnecessary.  <strong>What are all the <code>.cfi_XXX</code> lines for?  Why are so many labels added?  What do <code>.section</code>, <code>.ident</code>, <code>.def .p2align</code>, etc. do?</strong></p>
  <p>I understand that many of the labels and symbols are included for debugging, but shouldn't these be stripped or omitted if I am not compiling with -g enabled?</p>
  <hr />
  <p><strong>UPDATE</strong></p>
  <p>To clarify, by saying</p>
  <blockquote>
  <p>This appears to me to be the least amount of code possible (but I
  realize could be quite wrong) to perform this admittedly trivial task.
  Is this form the most &quot;optimized&quot; version of my C program?</p>
  </blockquote>
  <p>I am not suggesting that I am trying to, or have achieved, an optimized version of this program.  I realize the program is useless and trivial.  I am just using it as a tool to learn assembly and how the compiler works.</p>
  <p>The core of why I added this bit is to illustrate why I am confused that the 4 line version of this assembly code can effectively achieve the same effect as the others.  It seems to me that GCC has added a lot of &quot;stuff&quot; whose purpose I cannot discern.</p>