# Linux Kernel Module Cheat

#### 28.1.1. ARMv8 aarch64 x31 register

Example: userland/arch/aarch64/x31.S

There is no X31 name, and the encoding can have two different names depending on the instruction:

- XZR: zero register:

  - https://stackoverflow.com/questions/42788696/why-might-one-use-the-xzr-register-instead-of-the-literal-0-on-armv8

  - https://community.arm.com/processors/f/discussions/3185/wzr-xzr-register-s-purpose

- SP: stack pointer

To make things more confusing, some aliases can take either name, which makes them alias to different things, e.g. MOV accepts both:

    mov x0, sp
    mov x0, xzr

and the first one is an alias to ADD while the second an alias to ORR.

The difference is documented on a per instruction basis. Instructions that encode 31 as SP say:

    if d == 31 then
      SP[] = result;
    else
      X[d] = result;

And then those that don’t say that, B1.2.1 "Registers in AArch64 state" implies the zero register:

> In instruction encodings, the value 0b11111 (31) is used to indicate the ZR (zero register). This indicates that the argument takes the value zero, but does not indicate that the ZR is implemented as a physical register.

This is also described on ARMv8 architecture reference manual C1.2.5 "Register names":

> There is no register named W31 or X31.

> The name SP represents the stack pointer for 64-bit operands where an encoding of the value 31 in the corresponding register field is interpreted as a read or write of the current stack pointer. When instructions do not interpret this operand encoding as the stack pointer, use of the name SP is an error.

> The name XZR represents the zero register for 64-bit operands where an encoding of the value 31 in the corresponding register field is interpreted as returning zero when read or discarding the result when written. When instructions do not interpret this operand encoding as the zero register, use of the name XZR is an error