General differences in 64 bit: Default size is 64 bits If you wanted 32, use movl, addl, etc. push and pop operate with 64 bits now 64-bit registers start with r rax, rdi, rbp, etc. Use 64-bit version when dealing with memory addresses If dealing with a C int, still use e (eax, etc) Unless you need to clear the whole register... System Calls: syscall replaces int 0x80 It's an instruction in x86_64 Fundamentally, it does the same thing Parameter order: rax: System Call Number After that: rdi, rsi, rdx, r10, r8, r9 An explanation: /usr/src/linux-source-6.1/arch/x86/entry/entry_64.S System call numbers are different Table at: /usr/src/linux-source-6.1/arch/x86/entry/syscalls/syscall_64.tbl Other than all that, they're pretty similar Exampls: Hello world with write: hw_64.s Demo with printf/scanf: functions_64.s Function Calls: Different calling convention (see Wikipedia) Now a lot of parameters go into registers Other than that, it's basically the same You need to have the stack aligned on a 16-byte boundary! As in, the last hex digit should be 0 Otherwise it'll mysteriously segfault