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)