aarch64 通用寄存器作用
31 个,(不是 32 这个 2 的 5 次方)
X0,X1,X2,......,X30
X0 ~ X7 用作参数传递和返回值存放。 X0 用于存放函数返回值。
X8 别名 XR,用于存放 函数 的返回值。
x0和x8 都用作返回值, 当返回值为基本数据类型时,存放在 X0中,如果返回值为 结构体对象,使用X8寄存器返回。具体过程如下:
a. 调用函数前,caller 设置X8寄存器的值,将其设置为 返回对象存放地址。
b. 子函数内部,将待返回对象拷贝到 x8 指向的地址处。
1 0000000000000010 <getPeoplrObj>: 2 10: d100c3ff sub sp, sp, #0x30 3 14: aa0803e0 mov x0, x8 4 18: aa0003e1 mov x1, x0 5 1c: 910003e0 mov x0, sp 6 20: a9400c02 ldp x2, x3, [x0] 7 24: a9000c22 stp x2, x3, [x1] 8 28: a9410c02 ldp x2, x3, [x0, #16] 9 2c: a9010c22 stp x2, x3, [x1, #16] 10 30: a9420c02 ldp x2, x3, [x0, #32] 11 34: a9020c22 stp x2, x3, [x1, #32] 12 38: 9100c3ff add sp, sp, #0x30 13 3c: d65f03c0 ret 14 15 0000000000000040 <main>: 16 40: a9bc7bfd stp x29, x30, [sp, #-64]! 17 44: 910003fd mov x29, sp 18 48: 910043a0 add x0, x29, #0x10 19 4c: aa0003e8 mov x8, x0 20 50: 94000000 bl 10 <getPeoplrObj> 21 54: d503201f nop 22 58: a8c47bfd ldp x29, x30, [sp], #64 23 5c: d65f03c0 ret
X9 ~ X15 在子函数中使用这些寄存器时,直接使用即可, 无需 save - use- restore。
X16 X17 intra-procedure call scratch register; IP0 IP1 。 用途是给 编译器 使用的。插入 垫片代码 的。
These can be used by call veneers and similar code. Veneers are small pieces of code which are
automatically inserted by the linker,
在使用 汇编时,编译器 无法插入 垫片代码,这两个寄存器就可以自己决定怎么使用了。
X18 platform register 平台寄存器。不要使用。
x19 ~ X28 callee saved registers. 子函数 使用 前,需要先保存,再覆盖。子函数 退出前,需要先恢复,再退出。
X29 FP 寄存器,frame pointer。
X30 LR 寄存器
LR FP SP 在函数调用中的配合使用
0000000000000020 <mul>:
20: a9bd7bfd stp x29, x30, [sp, #-48]!
24: 910003fd mov x29, sp
28: f9000bf3 str x19, [sp, #16]
2c: f90017a0 str x0, [x29, #40]
30: f90013a1 str x1, [x29, #32]
34: f94017a1 ldr x1, [x29, #40]
38: f94017a0 ldr x0, [x29, #40]
3c: 94000000 bl 0 <add>
40: aa0003f3 mov x19, x0
44: f94013a1 ldr x1, [x29, #32]
48: f94013a0 ldr x0, [x29, #32]
4c: 94000000 bl 0 <add>
50: 9b007e60 mul x0, x19, x0
54: f9400bf3 ldr x19, [sp, #16]
58: a8c37bfd ldp x29, x30, [sp], #48
5c: d65f03c0 ret
0000000000000060 <main>:
60: a9be7bfd stp x29, x30, [sp, #-32]!
64: 910003fd mov x29, sp
68: d2800081 mov x1, #0x4 // #4
6c: d2800060 mov x0, #0x3 // #3
70: 94000000 bl 20 <mul>
74: f9000fa0 str x0, [x29, #24]
78: d503201f nop
7c: a8c27bfd ldp x29, x30, [sp], #32
80: d65f03c0 ret
a. 自函数进入时,先降低 SP 获得栈空间
b. 将 caller 的 FP 和 LR 保存下来。
c. 将 FP 设置为自己的 SP
d. 如果 子函数内部 需要使用到X19 ~ X28 寄存器,将其值 save 到 栈空间 上面。
e. 传入的参数用 X0 ~ X7 访问,函数内局部变量在 栈空间中(使用 FP + 偏移访问),使用参数和函数内的局部变量进行 运算。
f. 运算结果放在 x0或 X8指向的地址处。
g. 从栈空间 恢复 X19 ~ x28 的值
h. 从栈空间 恢复 FP LR 的值, SP 升高。
i. ret 返回
=============
其他寄存器
XZR
PC
SP (SP_EL0, SP_EL1, SP_EL2, SP_EL3)
SPSR ( SPSR_EL1, SPSR_EL2, SPSR_EL3)
ELR ( ELR_EL1, ELR_EL2, ELR_EL3)