通用寄存器

共有32个通用寄存器 x0 ~ x31 和 1个pc寄存器,共33个; x寄存器的低32位为w寄存器,即w0 ~ w31;

使用情况:

  • x0 ~ x7: 用于传递子程序参数和结果, 使用时不需要保存, 超过8个参数采用堆栈传递; 64位返回结果使用x1:x0表示
  • x8: 用于保存子程序返回地址, 尽量不要使用
  • x9 ~ x15: 临时寄存器,使用不需要保存;调用者保存
  • x16 ~ x17:
  • x18: 平台寄存器,保留用于平台abi,尽量不使用
  • x19 ~ x28: 临时寄存器,使用时需要保存;被调用者保存
  • x29: 帧指针寄存器 fp
  • x30: 链接寄存器 lr
  • x31: 堆栈指针寄存器 sp 或零寄存器 zxr

向量、浮点寄存器

共有32个向量寄存器 v0 ~ v31; 向量寄存器有以下别名:

  • 全128位用q表示,即q0 ~ q31, 128 bit;
  • 低 64位用d表示,即d0 ~ d31, 64 bit;
  • 低 32位用s表示,即s0 ~ s31, 32 bit;
  • 低 16位用h表示,即h0 ~ h31, 16 bit;
  • 低 8位用b表示,即b0 ~ b31, 8 bit;
   0  8 16  32      64              128
v0 |--------------------------------|
b0 |__|
h0 |____|
s0 |________|
d0 |________________|
q0 |________________________________|

使用情况:

  • v0 ~ v7: 用于参数传递和保存,子程序不需要保存;
  • v8 ~ v15: 子程序需要保存这些寄存器的低64位;
  • v16 ~ v31: 子程序使用时不需要保存

注意事项

  • 尽量不要用寄存器: x8, x18
  • 需要保存的寄存器:x19 ~ x28d8 ~ d15

保存寄存器的代码:

// function start
stp d14, d15, [sp, #(-16 * 8)]!
stp d12, d13, [sp, #(16 * 1)]
stp d10, d11, [sp, #(16 * 2)]
stp d8,  d9,  [sp, #(16 * 3)]
stp x19, x20, [sp, #(16 * 4)]
stp x21, x22, [sp, #(16 * 5)]
stp x23, x24, [sp, #(16 * 6)]
stp x25, x26, [sp, #(16 * 7)]

// some code

ldp x25, x26, [sp, #(16 * 7)]
ldp x23, x24, [sp, #(16 * 6)]
ldp x21, x22, [sp, #(16 * 5)]
ldp x19, x20, [sp, #(16 * 4)]
ldp d8,  d9,  [sp, #(16 * 3)]
ldp d10, d11, [sp, #(16 * 2)]
ldp d12, d13, [sp, #(16 * 1)]
ldp d14, d15, [sp], #(16 * 8)

ret