Instructions
x86-64SYSCALL / SYSENTER / INT 0x80
x86-64 uses the SYSCALL instruction to enter the kernel; the older INT 0x80 is the 32-bit Linux interface — confusing them leads to incorrect syscall number mapping.
SYSCALL is the fast kernel-entry instruction for x86-64 (Long Mode). It
replaces the older SYSENTER (32-bit fast call) and INT 0x80 (legacy 32-bit
software interrupt) mechanisms.
x86-64 Linux syscall ABI
| Register | Role |
|---|---|
rax | Syscall number |
rdi | Argument 1 |
rsi | Argument 2 |
rdx | Argument 3 |
r10 | Argument 4 (not rcx — that's trashed by SYSCALL itself) |
r8 | Argument 5 |
r9 | Argument 6 |
rax (return) | Return value (negative errno on error) |
rcx and r11 are clobbered by SYSCALL — the CPU saves RIP in rcx
and RFLAGS in r11.
Example: write(1, buf, len)
mov rax, 1 ; SYS_write = 1
mov rdi, 1 ; fd = stdout
lea rsi, [rip + buf]; pointer to data
mov rdx, 13 ; length
syscall32-bit Linux INT 0x80 ABI (legacy)
; 32-bit ABI — different register layout AND different syscall numbers
mov eax, 4 ; SYS_write = 4 (not 1!)
mov ebx, 1
mov ecx, buf
mov edx, len
int 0x80Key difference: INT 0x80 uses ebx, ecx, edx, esi, edi, ebp;
SYSCALL uses rdi, rsi, rdx, r10, r8, r9. The syscall numbers
also differ entirely between the two ABIs.
Reverse-engineering notes
- When analysing shellcode, the calling convention (
rdi/rsivsebx/ecx) immediately reveals whether it targets the 64-bit or 32-bit ABI. int 0x80in a 64-bit binary is valid but unusual — often seen in shellcode that was ported from 32-bit or in intentionally compact stagers.- The
vsyscall/vDSOpage maps common syscalls (likegettimeofday) as regular functions to avoid the kernel-transition overhead; calls to0xFFFFFFFFFF600000are vsyscall stubs, not directSYSCALLinstructions. - On Windows, the syscall number (SSN) varies per OS version and patch level —
making direct
syscallin user-mode shellcode (a "direct syscall") a technique for bypassing security tools that hookntdll.dll.