AArch64寄存器介绍

描述

 

 

 

作者简介

周文嘉,目前就职于某国产 AI GPU 芯片公司,曾服务于 ARM、阿里巴巴、HTC 等公司,拥有 10 年以上工作经验,主要从事系统软件开发,涵盖系统库开发、指令集优化、Linux内核开发等,为某些开源社贡献过一定数量的补丁,担任 Free time team 创始人,致力于免费教育事业。

 

邵靖杰,目前就职于某国产大型机 ARM CPU 研究所,主要从事众核处理器的系统级缓存研发工作。 

 

张健,先后在 SUSE、华为、区块链创业公司、寒武纪等公司工作,担任工程师、架构师、技术合伙人等,研究方向包括 ARM、Linux 发行版、Linux 内核、RISC-V 和虚拟化。

……

 

目录

1.2 AArch64 寄存器堆................................2 

 1.2.1 通用寄存器 ...................................2 

 1.2.2 特殊寄存器 ...................................2 

 1.2.3 系统控制寄存器 ...........................2 

 1.2.4 处理器状态 ...................................3 

 1.2.5 函数调用标准 ...............................4

 

作为 RISC 架构,AArch64 提供了大量的通用寄存器。除通用寄存器之外,本节还会介绍特殊寄存器、系统控制寄存器、处理器状态、函数调用标准。

 

1.2.1 通用寄存器 

通用寄存器分为两类。其中一类寄存器包括 X0~X30,用于普通的指令集,每个寄存器都有 64 位(Xn)和 32 位(Wn)两种表示形式。其中 32 位的表示形式是 64 位表示形式的低 32位。另一类寄存器包括 V0~V31,用于浮点运算、SIMD、crypto 等领域。每个寄存器长度都是128 位(Qn),它们有 64 位(Dn)、32 位(Sn)、16 位(Hn)、8 位(Bn)这 4 种表示形式。以 X0 和 V0 为例,X0 是 64 位寄存器,它的低 32 位是 W0。V0 也称为 Q0,Q0 是一个128 位的寄存器,它的低 64 位称为 D0,它的低 32 位称为 S0,它的低 16 位称为 H0,它的低8 位称为 B0,如图 1.1 所示。

 

函数调用

1.2.2 特殊寄存器 

XZR 和 WZR 分别对应 64 位与 32 位的零寄存器。对这些寄存器进行读操作,将会获取到0;对这些寄存器进行的写操作将会被处理器忽略。与 ARM 的 32 位架构不同,PC 寄存器已经不再是一个通用寄存器,无法直接访问。ARM 指令的长度是 4 字节,因此对于 ARMv8 上的纯 ARM 指令来说,PC 寄存器是按字节对齐的。SP 寄存器也不再是一个通用寄存器,SP寄存器强制按 16 字节对齐。 

 

1.2.3 系统控制寄存器 

ARM 的系统控制寄存器都以“_ELx”为后缀,其中“x”表示某异常级别(Exception Level,EL)的一个数字,如 SCTLR_EL1。后缀的数字意味着能够访问该寄存器的最低异常级别,ARM的系统控制寄存器如表 1.1 所示。

函数调用

MRS 和 MSR 指令用于读写系统控制寄存器,示例代码如下。

  •  
  •  
MRS    X0, SCTLR_EL1     // X0 = SCTLR_EL1 MSR    SCTLR_EL1, X0     // SCTLR_EL1 = X0

常用的系统控制寄存器及其功能如表 1.2 所示。

函数调用

ARM 的系统控制寄存器数量庞大,详细的介绍可以参考文档 DDI0487F_b_ARMv8_arm.pdf。

 

1.2.4 处理器状态 
 

AArch64 通过 PSTATE(process state)的标志位来保存处理器的状态,处理器执行指令的时候,可以读取和设置这些标志位。这些标志位既可以通过 mrs/msr 指令进行访问,也可以通过 DAIFSet、DAIFClr、SPSel、PAN、UAO 等指令直接访问。PSTATE 寄存器的标志位如表 1.3 所示。

函数调用

1.2.5 函数调用标准 

 

1.AArch64 基本指令集函数调用规则 
 

AArch64 提供了 31 个 64 位的通用寄存器 X0~X30,SP 寄存器已经变成了一个专用寄存器。这些寄存器的描述如表 1.4 所示。

 

函数调用

函数调用

 

值得注意的是,X16 和 X17 寄存器在动态链接的时候,可能会被某些链接器用于实现特殊功能。X18 寄存器在 Darwin 和 Windows 平台上会保留作为平台寄存器使用。在代码优化的时候,这 3 个寄存器要谨慎使用。

 

2.AArch64 NEON 

指令集函数调用规则 AArch64 提供了 32 个 128 位的寄存器(V0~31),可以用来进行 SIMD 和浮点运算。其中,V0~V7 这 8 个寄存器用来传递参数和函数返回值,V8~V15 这 8 个寄存器需要由被调函数保存(只需要保存这些寄存器的低 64 位即可)。D8~D15 是 V8~V15 寄存器的低 64 位,因此通过如下的代码片段保存 D8~D15 的内容,就可以在函数中使用 V0~V31 这 32 个寄存器了。

  •  
  •  
  •  
  •  
  •  
stp        d8, d9, [sp, -192]! 
stp        d10, d11, [sp, 16] stp        d12, d13, [sp, 32] stp        d14, d15, [sp, 48] 

 

3.AArch64 SVE 
 

指令集函数调用规则 如果平台支持 SVE 扩展,那么 AArch64 会提供 32 个可变长的向量寄存器 Z0~Z31。每个寄存器都可以用来进行 SIMD 和浮点运算,其中 Z0~Z7 用来传递参数和函数返回值。Z8~Z15 这 8 个寄存器需要由被调函数保存(只需要保存这些寄存器的低 64 位即可)。AArch64 还为 SVE 提供了 16 个断言寄存器 P0~P15,其中 P0~P3 这 4 个寄存器用来传递参数和函数返回值。

 

 

 

  审核编辑:汤梓红


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分