title: C to assembly call convention 32bit vs 64bit
body: <p>I have been following the excellent book Programming Ground Up, wanting to learn assembly. Although not in the book at this point, I wanted to call my assembly function from C. on a 32 bit machine, this works as is when working from the book.</p>
  <p>What I do here is storing the first argument in <code>%ebx</code> and the second in <code>%ecx</code>.</p>
  <pre><code>.type power, @function
  .globl power
  power:
      pushq   %ebp
      movl    %esp, %ebp
      subl    $4, %esp
  
      movl    8(%ebp), %ebx
      movl    12(%ebp), %ecx
  </code></pre>
  <p>I compile this (and the rest of the function) into an object file, create a main.c, where I prototype the function and call it, something like this:</p>
  <pre><code>int power(int b, int x);
  int a = power(2, 1);
  </code></pre>
  <p>However, when I compile this on a 64 bit machine, I get some very unexpected results. I modified the obvious, like the fact that <code>%esp</code> and <code>%ebp</code> needs to be replaced with <code>%rsp</code> and <code>%rbp</code>, but digging with GDB reveals that the arguments are nowhere to be found on the stack!</p>
  <p>Checking out what happens by using the <code>-S</code> option to GCC I can see that instead of pushing the variables on the stack, GCC stores the arguments in registers.</p>
  <pre><code> movl $1, %esi
   movl $2, %edi
   call power
  </code></pre>
  <p>On the 32 bit machine, it does what I expect and push the arguments on the stack:</p>
  <pre><code> movl $1, 4(%esp)
   movl $2, (%esp)
   call power
  </code></pre>
  <p>Now what is going on here? Why does GCC pass the arguments in registers on 64 bit and on the stack on 32 bit? This is very confusing! And I can't find any mention on this anywhere. Is there anyone who can enlighten me on this situation?</p>