x86-64 & 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). 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 our x86-64 & 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.

ArgumentSystem V x86-64Windows x64ARM64 (AAPCS64)
1stRDIRCXX0
2ndRSIRDXX1
3rdRDXR8X2
4thRCXR9X3
5thR8StackX4
6thR9StackX5
7thStackStackX6
8thStackStackX7
9th+StackStackStack

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).

ArgumentSystem V x86-64Windows x64ARM64 (AAPCS64)
1st floatXMM0XMM0D0 / S0
2nd floatXMM1XMM1D1 / S1
3rd floatXMM2XMM2D2 / S2
4th floatXMM3XMM3D3 / S3
5th–8thXMM4–XMM7StackD4–D7 / S4–S7
9th+StackStackStack

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 TypeSystem V x86-64Windows x64ARM64 (AAPCS64)
Integer / PointerRAXRAXX0
2nd integer (struct)RDXX1
Float / DoubleXMM0XMM0D0 / S0
Large structHidden ptr in RDIHidden ptr in RCXX8 (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.

CategorySystem V x86-64Windows x64ARM64 (AAPCS64)
General-purposeRBX, RBP, R12–R15RBX, RBP, RDI, RSI, R12–R15X19–X29 (FP)
Link register— (return addr on stack)— (return addr on stack)X30 (LR)*
SIMD / Float— (none)XMM6–XMM15D8–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.

CategorySystem V x86-64Windows x64ARM64 (AAPCS64)
General-purposeRAX, RCX, RDX, RSI, RDI, R8–R11RAX, RCX, RDX, R8–R11X0–X18 (X16/X17 = IP0/IP1; X18 = platform register)
SIMD / FloatXMM0–XMM15XMM0–XMM5V0–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.

RuleSystem V x86-64Windows x64ARM64 (AAPCS64)
Alignment before call16-byte16-byte16-byte (SP must always be aligned)
Shadow spaceNone32 bytes (always required)None
Red zone128 bytes below RSPNoneNone
Stack directionGrows downGrows downGrows 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)

; 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

; 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)

// 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

Related Resources

Deep dive: x86-64 & 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

Scroll to Top