title: gcc x86-32 stack alignment and calling printf
body: <p>To the best of my knowledge, x86-64 requires the stack to be 16-byte aligned before a call, while <a href="https://stackoverflow.com/a/40325384/3163618">gcc with <code>-m32</code> doesn't require this for main</a>. </p>
  
  <p>I have the following testing code: </p>
  
  <pre><code>.data
  intfmt:         .string "int: %d\n"
  testint:        .int    20
  
  .text
  .globl main
  
  main:
      mov     %esp, %ebp
      push    testint
      push    $intfmt
      call    printf
      mov     %ebp, %esp
      ret
  </code></pre>
  
  <p>Build with <code>as --32 test.S -o test.o &amp;&amp; gcc -m32 test.o -o test</code>. I am aware that syscall write exists, but to my knowledge it cannot print ints and floats the way printf can.</p>
  
  <p>After entering main, a 4 byte return address is on the stack. Then interpreting this code naively, the two push calls each put 4 bytes on the stack, so call needs another 4 byte value pushed to be aligned. </p>
  
  <p>Here is the objdump of the binary generated by gas and gcc:</p>
  
  <pre><code>0000053d &lt;main&gt;:
   53d:   89 e5                   mov    %esp,%ebp
   53f:   ff 35 1d 20 00 00       pushl  0x201d
   545:   68 14 20 00 00          push   $0x2014
   54a:   e8 fc ff ff ff          call   54b &lt;main+0xe&gt;
   54f:   89 ec                   mov    %ebp,%esp
   551:   c3                      ret    
   552:   66 90                   xchg   %ax,%ax
   554:   66 90                   xchg   %ax,%ax
   556:   66 90                   xchg   %ax,%ax
   558:   66 90                   xchg   %ax,%ax
   55a:   66 90                   xchg   %ax,%ax
   55c:   66 90                   xchg   %ax,%ax
   55e:   66 90                   xchg   %ax,%ax
  </code></pre>
  
  <p>I am very confused about the push instructions generated. </p>
  
  <ol>
  <li>If two 4 byte values are pushed, how is alignment achieved?</li>
  <li>Why is 0x2014 pushed instead of 0x14? What is 0x201d?</li>
  <li>What does <code>call 54b</code> even achieve? Output of <code>hd</code> matches <code>objdump</code>. Why is this different in gdb? Is this the dynamic linker?</li>
  </ol>
  
  <p></p>
  
  <pre><code>B+&gt;│0x5655553d &lt;main&gt;                       mov    %esp,%ebp                      │
     │0x5655553f &lt;main+2&gt;                     pushl  0x5655701d                     │
     │0x56555545 &lt;main+8&gt;                     push   $0x56557014                    │
     │0x5655554a &lt;main+13&gt;                    call   0xf7e222d0 &lt;printf&gt;            │
     │0x5655554f &lt;main+18&gt;                    mov    %ebp,%esp                      │
     │0x56555551 &lt;main+20&gt;                    ret  
  </code></pre>
  
  <p>Resources on what goes on when a binary is actually executed are appreciated, since I don't know what's actually going on and the tutorials I've read don't cover it. I'm in the process of reading through <a href="https://lwn.net/Articles/631631/" rel="nofollow noreferrer">How programs get run: ELF binaries</a>. </p>