通用寄存器
共有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 ~ x28
和d8 ~ 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