Probably old news, but linux made some changes to the way you performs system calls under the x86_64 architecture. It used to be that you could call interrupt 0×80, but this has changed. It seems you can still call via an interrupt, but you can’t use the syscall numbers provided by asm/unistd.h as they have all been changed. The new and faster method is to use the SYSCALL operation. The semantics are slightly different, eax still holds the syscall number, but the argument list is reversed.

For example, on i386:

#include <stdlib.h>
#include <stdio.h>
#include <sys/unistd.h>
#include <sys/syscall.h>
 
int main() {
  long int ret;
  int fd = 0;
  char* str = "Hello World!\\n";
  int strlen = sizeof("Hello World!");
 
  /* ret = write(fd, str, strlen); */
  asm ("int $0x80;"
       : "=a" (ret)
       : "0" (SYS_write),
         "b" (fd),
         "c" (str),
         "d" (strlen)
      );
 
  return ret;
 
}
 
 
[Download this code: i386_syscall.c]

would become this on x86_64:

#include <stdlib.h>
#include <stdio.h>
#include <sys/unistd.h>
#include <sys/syscall.h>
 
int main() {
  long int ret;
  int fd = 0;
  char* str = "Hello World!\\n";
  int strlen = sizeof("Hello World!");
 
  /* ret = write(fd, str, strlen); */
  asm ("syscall;"
       : "=a" (ret)
       : "0" (SYS_write),
         "D" (fd),
         "S" (str),
         "d" (strlen)
      );
 
  return ret;
 
}
 
 
[Download this code: x86_64_syscall.c]