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)

 

posted @ 2022-03-05 10:37  张志伟122  阅读(1461)  评论(0编辑  收藏  举报