Skip to content

x86-64 and ARM64 Calling Conventions Cheat Sheet (2026)

This calling conventions cheat sheet provides a quick reference for parameter passing, register usage, and stack rules across the three major 64-bit calling conventions: System V AMD64 ABI (Linux/macOS x86-64), Windows x64, and AAPCS64 (ARM64/AArch64).

This calling conventions cheat sheet provides a quick reference for parameter passing, register usage, and stack rules across the three major 64-bit calling conventions: System V AMD64 ABI (Linux/macOS x86-64), Windows x64, and AAPCS64 (ARM64/AArch64). Bookmark this page for instant answers during debugging and reverse engineering sessions.

For the complete deep dive with working assembly examples and Godbolt links, see my x86-64 and ARM64 Calling Conventions Demystified post. The official specifications are the System V AMD64 ABI, Microsoft x64 calling convention, and AAPCS64.

Integer/Pointer Argument Passing

The first several integer and pointer arguments are passed in registers. Additional arguments spill to the stack in right-to-left order. Note that Windows x64 uses only 4 register slots, while System V and AAPCS64 use 6 and 8 respectively.

Argument System V x86-64 Windows x64 ARM64 (AAPCS64)
1st RDI RCX X0
2nd RSI RDX X1
3rd RDX R8 X2
4th RCX R9 X3
5th R8 Stack X4
6th R9 Stack X5
7th Stack Stack X6
8th Stack Stack X7
9th+ Stack Stack Stack

Floating-Point Argument Passing

Floating-point and SIMD arguments use a separate set of registers. On Windows x64, float arguments occupy the same positional slot as integers — if the 1st argument is a float, it goes in XMM0 (not RCX).

Argument System V x86-64 Windows x64 ARM64 (AAPCS64)
1st float XMM0 XMM0 D0 / S0
2nd float XMM1 XMM1 D1 / S1
3rd float XMM2 XMM2 D2 / S2
4th float XMM3 XMM3 D3 / S3
5th–8th XMM4–XMM7 Stack D4–D7 / S4–S7
9th+ Stack Stack Stack

Return Values

Return values follow similar patterns across conventions, but large struct returns differ significantly — ARM64 uses a dedicated indirect result register (X8) rather than stealing an argument register.

Return Type System V x86-64 Windows x64 ARM64 (AAPCS64)
Integer / Pointer RAX RAX X0
2nd integer (struct) RDX X1
Float / Double XMM0 XMM0 D0 / S0
Large struct Hidden ptr in RDI Hidden ptr in RCX X8 (indirect result)

Callee-Saved (Non-Volatile) Registers

These registers must be preserved across function calls. If a function uses them, it must save and restore their values (typically in the prologue/epilogue). This is critical knowledge for this calling conventions cheat sheet — getting callee-saved registers wrong causes subtle, hard-to-debug corruption.

Category System V x86-64 Windows x64 ARM64 (AAPCS64)
General-purpose RBX, RBP, R12–R15 RBX, RBP, RDI, RSI, R12–R15 X19–X29 (FP)
Link register — (return addr on stack) — (return addr on stack) X30 (LR)*
SIMD / Float — (none) XMM6–XMM15 D8–D15 (lower 64 bits of V8–V15)**

*X30 (LR) note: The link register is not formally in the same callee-saved class as X19–X28 in AAPCS64. It is preserved by non-leaf functions because bl clobbers it, so they must save/restore it in the prologue/epilogue. Leaf functions (which never call other functions) do not need to preserve X30.

*ARM64 SIMD note: For V8–V15, only the lower 64 bits (D8–D15) are callee-saved. The upper 64 bits of these registers are not preserved across calls. Registers V0–V7 and V16–V31 are entirely caller-saved (all 128 bits). If you use the full 128-bit Q8–Q15 registers, the upper halves will be lost across function calls.

Caller-Saved (Volatile) Registers

These registers may be destroyed by any function call. Save them before calling if you need their values afterward.

Category System V x86-64 Windows x64 ARM64 (AAPCS64)
General-purpose RAX, RCX, RDX, RSI, RDI, R8–R11 RAX, RCX, RDX, R8–R11 X0–X18 (X16/X17 = IP0/IP1; X18 = platform register)
SIMD / Float XMM0–XMM15 XMM0–XMM5 V0–V7, V16–V31 (all 128 bits); upper 64 bits of V8–V15

Stack & Alignment Rules

Stack alignment violations cause crashes on all three platforms. The shadow space requirement on Windows x64 is the single biggest source of bugs when porting Unix assembly to Windows.

Rule System V x86-64 Windows x64 ARM64 (AAPCS64)
Alignment before call 16-byte 16-byte 16-byte (SP must always be aligned)
Shadow space None 32 bytes (always required) None
Red zone 128 bytes below RSP None None
Stack direction Grows down Grows down Grows down

Side-by-Side Example: int add(int a, int b, int c)

The same function compiled under all three conventions shows the calling conventions cheat sheet rules in action. Notice how argument registers differ but the logic is identical.

System V x86-64 (Linux / macOS)

asm
; int add(int a, int b, int c)
; a = edi, b = esi, c = edx
add:
mov  eax, edi       ; eax = a
add  eax, esi       ; eax += b
add  eax, edx       ; eax += c
ret                 ; return in eax

Windows x64

asm
; int add(int a, int b, int c)
; a = ecx, b = edx, c = r8d
add:
mov  eax, ecx       ; eax = a
add  eax, edx       ; eax += b
add  eax, r8d       ; eax += c
ret                 ; return in eax

ARM64 (AAPCS64)

asm
// int add(int a, int b, int c)
// a = w0, b = w1, c = w2
add:
add  w0, w0, w1     // w0 = a + b
add  w0, w0, w2     // w0 += c
ret                 // return in w0

Deep dive: x86-64 and ARM64 Calling Conventions Demystified — full tutorial with Godbolt examples, struct passing rules, and variadic function handling.

Also see: Stack Frames & Function Prologues | Systems Programming Glossary

Official specs: System V AMD64 ABI | Microsoft x64 ABI | ARM AAPCS64

Coder Musings

A modern technical laboratory for systems programming. Master Assembly, Compilers, and Low-Level Engineering through curated paths and interactive visualizations.

© 2026 Coder Musings. All rights reserved. Built for the systems community.