title: Passing parameters when compile C and nasm
body: <p>When compiling C and nasm on Mac OS X, I found it is different to Linux when passing parameters and making system call. My code works but I'm really confused with it.<br>
  I write a function <code>myprint</code> in nasm to print string passed from C.</p>
  
  <p>Here is the C code <code>main.c</code> </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  void myprint(char* msg, int len);
  
  int main(void){
       myprint("hello\n",6);
       return 0;
  }
  </code></pre>
  
  <p>Here is the nasm code <code>myprint.asm</code></p>
  
  <pre><code>section .text
  
  global _myprint
  
  _syscall:
      int 0x80
      ret
  
  _myprint:
      push dword [esp+8]    ;after push, esp-4
      push dword [esp+8]
      push dword 1
      mov eax,4
      call _syscall
      add esp,12
      ret
  </code></pre>
  
  <p>Compile and link them:</p>
  
  <pre><code>nasm -f macho -o myprint.o myprint.asm
  gcc -m32 -o main main.c myprint.o
  </code></pre>
  
  <p>it prints "hello" correctly.</p>
  
  <p>As you can see, OS X(FreeBSD) use push to pass parameters to sys call, but the parameters <code>char*</code> and <code>int</code> are already pushed into the stack and their addresses are <code>esp+4</code> and <code>esp+8</code>. However, I have to read them from the stack and push them into stack again to make it work.<br>
  If I delete</p>
  
  <pre><code>push dword [esp+8]    ;after push, esp-4
  push dword [esp+8]
  </code></pre>
  
  <p>it will print lots of error codes and <code>Bus error: 10</code>, like this:</p>
  
  <pre><code>???]?̀?j????????
                 ?hello
  `44?4
       __mh_execute_headerm"ain1yprint6???;??
                                             &lt;??
                                                (
                                                 libSystem.B?
                                                             `%?. _syscall__mh_execute_header_main_myprintdyld_stub_binder ??z0&amp;?z?&amp;?z?&amp;?z۽??۽????N?R?N?o?N???N??N?e?N?h?N?0?zR?N???N???t??N?N???N?????@?`@b?`?`?a@c aaU??]N?zBus error: 10
  </code></pre>
  
  <p>Why it needs to push the parameters into stack again? How can I pass these parameters already in stack to syscall without pushing again?</p>