DEV Community

Cover image for AArch64 & X86 64 Registers and Instruction Quick Start
A Serputov
A Serputov

Posted on

AArch64 & X86 64 Registers and Instruction Quick Start

General-Purpose Registers For AArch64

The aarch64 registers are named:

  • r0 through r30 - to refer generally to the registers
  • x0 through x30 - for 64-bit-wide access (same registers)
  • w0 through w30 - for 32-bit-wide access (same registers - upper 32 bits are either cleared on load or sign-extended (set to the value of the most significant bit of the loaded value)).

Register '31' is one of two registers depending on the instruction context:

  • For instructions dealing with the stack, it is the stack pointer, named rsp
  • For all other instructions, it is a "zero" register, which returns 0 when read and discards data when written - named rzr (xzr, wzr)
    Usage during syscall/function call:

  • r0-r7 are used for arguments and return values; additional arguments are on the stack
    For syscalls, the syscall number is in r8

  • r9-r15 are for temporary values (may get trampled)

  • r16-r18 are used for intra-procedure-call and platform values (avoid)
    The called routine is expected to preserve r19-- r28 *** These registers are generally safe to use in your program.

  • r29 and r30 are used as the frame register and link register (avoid)

See the ARM Procedure Call Reference for details.

Floating-Point and SIMD Registers
Aarch64 also defines a set of large registers for floating-point and single-instruction/multiple-data (SIMD) operations. For details, refer to the ARM documentation.

Note the syntax:

  • Register names are not prefixed.
  • Immediate values are not prefixed with a character (they may be prefaced with # if desired).
  • Indirect memory access is indicated by [square brackets].
  • Hexadecimal values are indicated by a 0x prefix.
  • Character values are indicated by quotation marks. Escapes (such as '\n') are permitted.
  • Destinations are given as the first argument (mov r0, r1 moves INTO r0 FROM r1; you can think of this as r0=r1).
  • For the LDR/STR instructions: you can append a character indicating the number of bits (lowest) to be loaded or stored:
  • Q = Quadword = 64 bits
  • D = Double word = 32 bits
  • W = Word = 16 bits
  • B = Byte = 8 bits

General-Purpose Registers For X86 64

The 64-bit versions of the 'original' x86 registers are named:

  • rax - register a extended
  • rbx - register b extended
  • rcx - register c extended
  • rdx - register d extended
  • rbp - register base pointer (start of stack)
  • rsp - register stack pointer (current location in stack, growing downwards)
  • rsi - register source index (source for data copies)
  • rdi - register destination index (destination for data copies)

The registers added for 64-bit mode are named:

  • r8 - register 8
  • r9 - register 9
  • r10 - register 10
  • r11 - register 11
  • r12 - register 12
  • r13 - register 13
  • r14 - register 14
  • r15 - register 15

These may be accessed as:

  • 64-bit registers using the 'r' prefix: rax, r15
  • 32-bit registers using the 'e' prefix (original registers: e_x) or 'd' suffix (added registers: r__d): eax, r15d
  • 16-bit registers using no prefix (original registers: x) or a 'w' suffix (added registers: r_w): ax, r15w
  • 8-bit registers using 'h' ("high byte" of 16 bits) suffix (original registers - bits 8-15: _h): ah, bh
  • 8-bit registers using 'l' ("low byte" of 16 bits) suffix (original registers - bits 0-7: l) or 'b' suffix (added registers: r_b): al, bl, r15b

Usage during syscall/function call:

  • First six arguments are in rdi, rsi, rdx, rcx, r8d, r9d; remaining arguments are on the stack.
  • For syscalls, the syscall number is in rax. For procedure calls, rax should be set to 0.
  • Return value is in rax.
  • The called routine is expected to preserve rsp,rbp, rbx, r12, r13, r14, and r15 but may trample any other registers.

Floating-Point and SIMD Registers

x86_64 also defines a set of large registers for floating-point and single-instruction/multiple-data (SIMD) operations. For details, refer to the Intel or AMD documentation.

Note the syntax:

  • Register names are prefixed by %
  • Immediate values are prefixed by $
  • Indirect memory access is indicated by (parenthesis).
  • Hexadecimal values are indicated by a 0x prefix.
  • Character values are indicated by quotation marks. Escapes (such as '\n') are permitted.
  • Data sources are given as the first argument (mov %r10,%r11 moves FROM r10 INTO r11).

For the MOV instruction:

  • You can append a suffix indicating the amount of data to be moved -- e.g., q for quadword (64 bits), d for doubleword (32 bits), w for word (16 bits), or b for byte (8 bits).

Conclusion

⚠️ Computer Architecture Blog Post: Link

Links

🖇 Follow me on GitHub

🖇 Follow me on Twitter

_p.s This post was made for my Software Portability and Optimization class.

Top comments (0)