Calling Conventions

Registers are fast, low-level storage locations inside the CPU. While x86_64 offers 16 general-purpose registers, their usage is often guided by conventions rather than absolute freedom.

The use of these registers usually depends on the context. Primarily there exist two contexts:

  1. Function Call Context
  2. System Call Context

How the registers would be used in the above two contexts is defined in a system-level agreement, called ABI, which stands for Application Binary Interface.

As long as we are out of these two contexts, we can use a register as we want. And we will demonstrate this later.

Function Call Convention

ArgumentRegisterDescription
Syscall #raxIdentifier
Argument 1rdiFirst parameter
Argument 2rsiSecond parameter
Argument 3rdxThird parameter
Argument 4r10Fourth parameter
Argument 5r8Fifth parameter
Argument 6r9Sixth parameter

Syscall Convention

RegisterPurpose / Convention
raxAccumulator; return values, syscall #
rbxBase register; often callee-saved
rcxCounter for loops, shifts
rdxData register; I/O, syscall args
rsiSource index; memory ops, args
rdiDestination index; memory ops, args
rbpBase pointer; stack frame reference
rspStack pointer; top of the stack
r85th syscall argument
r96th syscall argument
r104th syscall argument
r11Temporary scratch for syscall
r12–r15Callee-saved; general-purpose

Note: Caller is the function that makes a call to another function. The function that is being called is termed as callee.

  • When a register is callee-saved, the callee function must preserve the state of that register if it wants to use it and restore its state before returning.
  • When a register is caller-saved, the caller function must preserve its state if it wants to use it later because a function call in-between might use it and it has no reason to preserve its state.

In Linux (x86_64), the most common calling convention is System V AMD64 ABI. It defines how functions and system calls exchange data by assigning specific roles to specific registers.

To successfully invoke a system call, our data must be placed in these registers accordingly. Otherwise, the kernel will not interpret our request correctly.

But Why Do These Conventions Even Exist?

System V ABI (where V is 5) is not the only ABI that exist. It is the one that Linux uses. Microsoft Windows 64-bit uses x64 ABI.

If every organization used their own calling convention, one thing is sure to suffer — cross-compatibility. These ABIs are contracts that everyone agrees upon. When every system uses the same convention, cross-compatibility improved. Software support improved.

Last updated on