title: What is the correct constant for the exit system call?
body: <p>I am trying to learn x86_64 assembly, and am using GCC as my assembler. The exact command I'm using is:</p>
  
  <pre><code>gcc -nostdlib tapydn.S -D__ASSEMBLY__
  </code></pre>
  
  <p>I'm mainly using gcc for its preprocessor. Here is <code>tapydn.S</code>:</p>
  
  <pre><code>.global _start
  
  #include &lt;asm-generic/unistd.h&gt;
  
  syscall=0x80
  
  .text
  _start:
      movl $__NR_exit, %eax
      movl $0x00, %ebx
      int  $syscall
  </code></pre>
  
  <p>This results in a segmentation fault. I believe the problem is with the following line:</p>
  
  <pre><code> movl $__NR_exit, %eax
  </code></pre>
  
  <p>I used <code>__NR_exit</code> because it was more descriptive than some magic number. However, it appears that my usage of it is incorrect. I believe this to be the case because when I change the line in question to the following, it runs fine:</p>
  
  <pre><code>movl $0x01, %eax
  </code></pre>
  
  <p>Further backing up this trail of thought is the contents of <code>usr/include/asm-generic/unistd.h</code>:</p>
  
  <pre><code>#define __NR_exit 93
  __SYSCALL(__NR_exit, sys_exit)
  </code></pre>
  
  <p>I expected the value of __NR_exit to be 1, not 93! Clearly I am misunderstanding its purpose and consequently its usage. For all I know, I'm getting lucky with the <code>$0x01</code> case working (much like undefined behaviour in C++), so I kept digging...</p>
  
  <p>Next, I looked for the definition of <code>sys_exit</code>. I couldn't find it. I tried using it anyway as follows (with and without the preceeding $):</p>
  
  <pre><code>movl $sys_exit, %eax
  </code></pre>
  
  <p>This wouldn't link:</p>
  
  <pre><code>/tmp/cc7tEUtC.o: In function `_start':
  (.text+0x1): undefined reference to `sys_exit'
  collect2: error: ld returned 1 exit status
  </code></pre>
  
  <p>My guess is that it's a symbol in one of the system libraries and I'm not linking it due to my passing <code>-nostdlib</code> to GCC. I'd like to avoid linking such a large library for just one symbol if possible.</p>
  
  <p>In response to Jester's comment about mixing 32 and 64 bit constants, I tried using the value <code>0x3C</code> as suggested:</p>
  
  <pre><code>movq $0x3C, %eax
  movq $0x00, %ebx
  </code></pre>
  
  <p>This also resulting a segmentation fault. I also tried swapping out <code>eax</code> and <code>ebx</code> for <code>rax</code> and <code>rbx</code>:</p>
  
  <pre><code>movq $0x3C, %rax
  movq $0x00, %rbx
  </code></pre>
  
  <p>The segmentation fault remained.</p>
  
  <p>Jester then commented stating that I should be using <code>syscall</code> rather than <code>int $0x80</code>:</p>
  
  <pre><code>.global _start
  
  #include &lt;asm-generic/unistd.h&gt;
  
  .text
  _start:
      movq $0x3C, %rax
      movq $0x00, %rbx
      syscall
  </code></pre>
  
  <p>This works, but I was later informed that I should be using <code>rdi</code> instead of <code>rbx</code> as per the System V AMD64 ABI:</p>
  
  <pre><code>movq $0x00, %rdi
  </code></pre>
  
  <p>This also works fine, but still ends up using the magic number <code>0x3C</code> for the system call number.</p>
  
  <p>Wrapping up, my questions are as follows:</p>
  
  <ul>
  <li>What is the correct usage of <code>__NR_exit</code>?</li>
  <li>What should I be using instead of a magic number for the <code>exit</code> system call?</li>
  </ul>