x86_64

keywords: x86_64, x86, abi

  • 64bit synonyms: x86_64, x64, amd64, intel 64
  • 32bit synonyms: x86, ia32, i386
  • ISA type: CISC
  • Endianness: little

Registers

General purpose register

bytes
[7:0]      [3:0]   [1:0]   [1]   [0]     desc
----------------------------------------------------------
rax        eax     ax      ah    al      accumulator
rbx        ebx     bx      bh    bl      base register
rcx        ecx     cx      ch    cl      counter
rdx        edx     dx      dh    dl      data register
rsi        esi     si      -     sil     source index
rdi        edi     di      -     dil     destination index
rbp        ebp     bp      -     bpl     base pointer
rsp        esp     sp      -     spl     stack pointer
r8-15      rNd     rNw     -     rNb

Special register

bytes
[7:0]      [3:0]     [1:0]      desc
---------------------------------------------------
rflags     eflags    flags      flags register
rip        eip       ip         instruction pointer

FLAGS register

rflags
bits  desc
-----------------------------
[11]  OF overflow flag
[10]  DF direction flag
 [7]  SF sign flag
 [6]  ZF zero flag
 [4]  AF auxiliary carry flag
 [2]  PF parity flag
 [0]  CF carry flag

Addressing

movw [rax], rbx         // save val in rbx at [rax]
movw [imm], rbx         // save val in rbx at [imm]
movw rax, [rbx+4*rcx]   // load val at [rbx+4*rcx] into rax

rip relative addressing:

lea rax, [rip+.my_str]       // load addr of .my_str into rax
...
.my_str:
.asciz "Foo"

Size directives

Explicitly specify size of the operation.

mov  byte ptr [rax], 0xff    // save 1 byte(s) at [rax]
mov  word ptr [rax], 0xff    // save 2 byte(s) at [rax]
mov dword ptr [rax], 0xff    // save 4 byte(s) at [rax]
mov qword ptr [rax], 0xff    // save 8 byte(s) at [rax]

SysV x86_64 ABI

Passing arguments to functions

  • Integer/Pointer arguments
    reg     arg
    -----------
    rdi       1
    rsi       2
    rdx       3
    rcx       4
    r8        5
    r9        6
    
  • Floating point arguments
    reg     arg
    -----------
    xmm0      1
      ..     ..
    xmm7      7
    
  • Additional arguments are passed on the stack. Arguments are pushed right-to-left (RTL), meaning next arguments are closer to current rsp.

Return values from functions

  • Integer/Pointer return values
    reg          size
    -----------------
    rax        64 bit
    rax+rdx   128 bit
    
  • Floating point return values:
    reg            size
    -------------------
    xmm0         64 bit
    xmm0+xmm1   128 bit
    

Caller saved registers

Caller must save these registers if they should be preserved across function calls.

  • rax
  • rcx
  • rdx
  • rsi
  • rdi
  • rsp
  • r8 - r11

Callee saved registers

Caller can expect these registers to be preserved across function calls. Callee must must save these registers in case they are used.

  • rbx
  • rbp
  • r12r15

Stack

  • grows downwards
  • frames aligned on 16 byte boundary
    HI ADDR
     |                +------------+
     |                | prev frame |
     |                +------------+ <--- 16 byte aligned (X & ~0xf)
     |       [rbp+8]  | saved RIP  |
     |       [rbp]    | saved RBP  |
     |       [rbp-8]  | func stack |
     |                | ...        |
     v                +------------+
    LO ADDR
    

ASM skeleton

Small assembler skeleton, ready to use with following properties:

  • use raw Linux syscalls (man 2 syscall for ABI)
  • no C runtime (crt)
  • gnu assembler gas
  • intel syntax
# file: greet.s

    .intel_syntax noprefix

    .section .text, "ax", @progbits
    .global _start
_start:
    mov rdi, 1                      # fd
    lea rsi, [rip + greeting]       # buf
    mov rdx, [rip + greeting_len]   # count
    mov rax, 1                      # write(2) syscall nr
    syscall

    mov rdi, 0                      # exit code
    mov rax, 1                      # exit(2) syscall nr
    syscall

    .section .rdonly, "a", @progbits
greeting:
    .asciz "Hi ASM-World!\n"
greeting_len:
    .int .-greeting

Syscall numbers are defined in /usr/include/asm/unistd.h.

To compile and run:

> gcc -o greet greet.s -nostartfiles -nostdlib && ./greet
Hi ASM-World!

References