title: Stack cleanup on IA32 after call/ret
body: <p>I just started learning x86 and don't quite understand how the stack is cleaned up after a call/ret on IA32. I compiled the following code with <code>gcc -m32 -no-pie</code>:</p>
  <pre class="lang-c prettyprint-override"><code>#include &lt;unistd.h&gt;
  
  int main()
  {
      char text[108];
      int x = read(0, text, 108);
      return 0;
  }
  </code></pre>
  <p>As far as I understand, the compiler makes space for 120 (116 + 4 bytes) on the stack. The first two words <code>ebp-4</code> and <code>ebp-8</code> remain unused (for memory alignment maybe?), and <code>ebp-12</code> is reserved for storing <code>x</code>. <code>ebp-16</code> to <code>ebp-120</code> is reserved for the input text. Before calling <code>read</code> three values (4 bytes each) are pushed onto the stack, which are (after RET) later cleaned up with <code>add esp, 16</code>. But shouldn't it be <code>add esp, 12</code> since we only pushed 3 values? Is it not overwriting the first/last character of &quot;text&quot;? I already drew the stack multiple times on paper, but I still don't see my mistake.</p>
  <pre><code>lea     ecx, [esp+4]
  and     esp, -16
  push    DWORD PTR [ecx-4]
  push    ebp
  mov     ebp, esp
  push    ecx
  sub     esp, 116
  sub     esp, 4
  push    108
  lea     eax, [ebp-120]
  push    eax
  push    0
  call    read
  add     esp, 16
  mov     DWORD PTR [ebp-12], eax
  mov     eax, 0
  mov     ecx, DWORD PTR [ebp-4]
  leave
  lea     esp, [ecx-4]
  ret
  </code></pre>
  <p><strong>Edit:</strong> Shouldn't also at the very end the stack and base pointers be restored, i.e., <code>mov esp, ebp ; pop ebp</code> so that the very last <code>ret</code> can access the stored instruction pointer and jump out of the main function?</p>