ARMv8体系结构基础01:ARMv8体系结构简介

目录

1 ARMv8体系结构特性

2 ARMv8体系结构基本概念

2.1 处理机(Processing Element, PE)

2.2 异常等级(Exception Level)

2.2.1 异常等级概述

2.2.2 安全状态(security state)

2.2.3 异常等级切换

2.3 执行状态(Execution State)

2.3.1 执行状态概述

2.3.2 AArch64执行状态

2.3.3 AArch32执行状态

2.3.4 执行状态切换

3 AArch64中的寄存器

3.1 通用寄存器

3.2 特殊寄存器

3.2.1 零寄存器(Zero Register)

3.2.2 PC指针(Program Counter)

3.2.3 栈指针(Stack Pointer,SP)

3.2.4 保存处理状态寄存器(Saved Process Status Register,SPSR)

3.2.5 异常链接寄存器(Exception Link Register,ELR)

3.3 PSTATE寄存器

3.3.1 PSTATE状态位

3.3.2 PSTATE状态位的访问

3.4 系统寄存器

4 ARMv8实现示例

4.1 Cortex-A53 & Cortex-A57

4.2 Cortex-A72

5 其他内容

5.1 支持数据类型

5.2 调试类型概述

5.2.1 Self-hosted debug

5.2.2 External debug


1 ARMv8体系结构特性

ARMv8体系结构基础01:ARMv8体系结构简介_第1张图片

 

1. 由于使用64位体系结构,因此处理器可以访问远超4GB的物理地址空间

说明1:虽然是64位体系结构,但是一般并不使用64位地址总线,例如使用48位,即可以访问256TB的物理地址空间

说明2:在32位ARM体系结构中,如果不使能LPAE(Large Physical Address Extension)功能,最多只能访问4GB物理地址空间。即使使能了LPAE功能,也只是将物理地址空间的寻址能力扩展到40位,也就是1TB

2. 提供64位的虚拟地址寻址,从而扩大了进程的虚拟地址空间

说明1:在32位ARM体系结构中,即使使能了LAPE功能,也只是扩展了物理地址空间,但是进程的虚拟地址空间还是只有4GB

说明2:扩大虚拟地址空间之后,桌面系统软件和服务器软件可以从如下方面获益

① 可以使用memory map的方式映射更大的文件到进程虚拟地址空间中,从而提高IO的效率

② 可以使用稀疏编址(sparse addressing),具体可参考64位体系结构中的进程地址空间布局

3. 通过automatic event signaling机制实现高性能低功耗的spinlock

4. 提供31个64位通用寄存器,可减少对栈的使用,从而提升性能

说明:在ARMv7体系结构的AAPCS(ARM Architecture Procedure Call Standard)中,前4个参数使用寄存器传递,后续参数需要使用栈传递,也就是需要访问内存。而在ARMv8体系结构中,可以使用寄存器传递前8个参数,从而减少了对栈的使用

5. 提供了更高效的64位立即数生成方式,减少对文字池(literal pool)的使用,也就减少了对内存的访问

说明:在ARMv7体系结构中,LDR伪指令可用于装置一个32位常数或一个地址到寄存器,语法如下

LDR register, =expr @expr为32位常量表达式

在实现中,

① 如果expr的值没有超过MOV或MVN指令的取值范围,汇编器用一条MOV或MVN指令代替LDR伪指令

② 当expr表示的值超过MOV和MVN指令的取值范围,汇编器将常数放入数据文字池,同时用一条基于PC的LDR转载指令读取该常数。同时,文字池所在地址与LDR伪指令处的PC值之间的偏移是有限制的,在ARM指令中为±4KB

6. 提供基于PC寄存器±4GB的相对寻址范围,提高了相对寻址效率,可以提升动态库和位置无关代码的执行效率

7. 支持16KB & 64KB的分页粒度,可以减少页表级数,同时提高TLB命中率

8. 全新的异常处理模型,更加利于操作系统和虚拟化的实现

9. 提供高效的Cache管理机制

① 可以在用户空间进行Cache操作

② Data Cache Zero指令可以快速清空Data Cache

10. 提供硬件加速的加密功能

11. 专门为C++11、C11和Java的内存模型设计了全新的Load-Acquire和Store-Release指令,在线程安全的代码中,不再需要显式的内存屏障指令,从而提升了性能

12. NEON提供双精度浮点型SIMD指令,可用于各种算法、高性能计算(High Performance Computing,HPC)和超级计算机中

说明1:从ARMv8体系结构特性可见,该体系结构提升性能很重要的一点就是减少对内存的访问

说明2:从32位体系结构切换到64位体系结构的开销

① 在64位体系结构中,指针长度从4B增加到8B,会带来内存使用上的开销

② 在64位体系结构中,可使用物理地址空间和虚拟地址空间巨大,会导致Cache命中率的降低,从而降低性能

因为Cache生效的基础是局部性原理,但是在程序在巨大地址空间中的转移,就破坏了局部性原理

2 ARMv8体系结构基本概念

2.1 处理机(Processing Element PE

1. 在ARMv8体系结构中,将处理器处理事务的抽象过程定义为PE(引入的一个新名词),可以将PE简单理解为处理器核心

2. 在一个符合ARMv8体系结构实现的处理器上,编程者看到的处理器行为必须和抽象的PE顺序执行看到的行为一致

2.2 异常等级(Exception Level

ARMv8体系结构基础01:ARMv8体系结构简介_第2张图片

2.2.1 异常等级概述

1. 异常等级确定了处理器当前的特权级别,ELn的数值越大特权级别越高

2. 典型的异常等级使用如下,

EL0:用户特权,用于运行普通用户程序

EL1:系统特权,通常运行操作系统内核

EL2:运行虚拟化扩展的虚拟机监控程序(Hypervisor)

EL3:运行安全世界中的安全监控器(Secure Monitor)

说明1:通常情况下,每层软件都运行在一个异常等级中。但是有个例外,就是在操作系统内核中实现的hypervisor(e.g. KVM),他运行在EL1和EL2中

说明2:在基于ARMv8体系结构的处理器实现中,EL0和EL1是必须实现的,而EL2和EL3的实现是可选的。同时,异常等级的实现也不需要是连续的,例如可以实现EL0、EL1和EL3

2.2.2 安全状态(security state

2.2.2.1 安全状态概述

1. ARMv8体系结构提供2种安全状态,Secure和Non-secure,每种安全状态有独立的物理地址空间范围

2. 在Secure statePE可以访问SecureNon-secure的物理地址空间范围

3. 在Non-secure statePE只能访问Non-secure的物理地址空间范围

说明1:Secure state和Non-secure state将运行环境划分为Normal world和Secure world

说明2:EL3只存在于Secure state

2.2.2.2 安全状态组件

在图示的结构中,Secure state包含了如下2个组件

1. Secure firmware

① 运行在Secure state + EL0

② Secure firmware必须是系统启动后运行的首个程序

③ Secure firmware用于进行平台初始化,Trusted OS的安装,以及SMC(Secure Monitor Calls)的路由

2. Trusted OS

① 运行在Secure state + EL1

② Trusted OS向Normal world提供服务,同时为运行Secure或Trusted应用程序提供环境

说明1:Secure monitor用于实现Normal world和Secure world的切换

① 从Non-secure state切换到Secure state,只能通过触发到(take to)EL3的异常实现

② 从Secure state切换到Non-secure state,只能通过从EL3的异常返回(return from)实现

说明2:在图示的结构中,Hypervisor只能运行在Normal world。在ARMv8.4体系结构改进中,增加了运行在Secure state + EL2的Secure Hypervisor

ARMv8体系结构基础01:ARMv8体系结构简介_第3张图片

说明3:结合异常等级和安全状态,PE总是处于某种异常等级和安全状态,此时PE可以访问如下资源

① 当前异常等级和当前安全状态可用的资源

e.g. 在EL1 + Non-secure状态下,可以访问EL1 + Non-secure相应的的资源

② 当前安全状态且异常等级低于当前当前等级的资源

e.g. 在EL1 + Non-secure状态下,还可以访问EL0 + Non-secure相应的资源

同时注意安全状态的规则,即在Secure状态下,PE可以访问Secure和Non-secure的资源。又由于EL3只能运行在Secure状态下,所以EL3可以访问所有异常等级 + 安全状态对应的资源

2.2.3 异常等级切换

2.2.3.1 异常相关术语

2.2.3.1.1 taking an exception

1. taken from

PE第一次响应异常条件时的状态

2. taken to

PE在taking一个异常后的状态

说明:简单来说,take from就是在某个异常等级触发了异常,take to就是异常导致PE进入的异常等级

2.2.3.1.2 returning from an exception

1. returns from

PE提交异常返回指令(ERET指令)准备执行的状态

2. returns to

异常返回指令开始执行时的状态

说明:同样的,returns from就是从某个异常等级返回,return to就是异常要返回的异常等级

2.2.3.2 异常等级切换时机

1. 处理异常时

2. 从异常返回时

2.2.3.3 异常等级切换规则

1. 当发生一个异常时,异常等级只能上升或维持不变

2. 当从一个异常返回时,异常等级只能下降或维持不变

说明:target exception level

① 一个异常要进入的异常等级,称作target exception level

② EL0不能作为target exception level,也就是说所有异常都不会在EL0中处理

③ 一个异常的target exception通过如下2种方式指定,

  • 隐含在异常类型中
  • 通过系统寄存器(System register)指定

2.3 执行状态(Execution State

2.3.1 执行状态概述

1. ARMv8体系结构提供了2种执行状态,AArch64和AArch32,其中AArch32执行状态用于实现与ARMv7体系结构兼容

2. 执行状态定义了PE的执行环境,这个环境包括,

① 寄存器宽度

② 指令集

③ 异常模式

④ 虚拟内存系统结构(Virtual Memory System Architectural,VMSA)

⑤ 编程模型

2.3.2 AArch64执行状态

1. 提供31个64位的通用寄存器

2. 提供64位的程序计数寄存器PC、栈指针SP和异常链接寄存器ELR

3. 提供32个128位的用于SIMD与浮点运算寄存器

4. 提供A64指令集

5. 使用ARMv8异常模型,支持4个异常等级(EL0 ~ EL3)

6. 支持64位的虚拟内存寻址

7. 使用一组处理器状态(PSTATE)寄存器保存PE状态

8. 每个系统寄存器命名时,带有异常等级后缀,该后缀决定了可访问该寄存器的最低异常等级

2.3.3 AArch32执行状态

1. 提供13个32位的通用寄存器

2. 提供32位的程序计数寄存器PC、栈指针SP和链接寄存器LR,其中LR同时也用作ELR

3. 提供32个64位的用于SIMD和浮点运算的寄存器

4. 提供A32和T32指令集

5. 支持ARMv7-A异常模型,实现时将PE模式映射到ARMv8的异常模型

6. 支持32位的虚拟地址寻址

7. 使用一组处理器状态(PSTATE)寄存器保存PE状态,A32和T32指令通过APSR和CPSR访问

说明:执行状态有运行时和编译时的要求,二者要匹配。运行时由系统寄存器标识,编译时由编译器控制

注意:AArch32不是本系列笔记的分析重点

2.3.4 执行状态切换

2.3.4.1 执行状态切换场景

1. 假设我们需要在一个64位操作系统上运行32位的应用程序,就需要将执行状态从AAch64切换到AArch32

2. 当32位应用程序运行完成时,或者需要陷入64位操作系统执行时,就需要将执行状态从AArch32再切换回AArch64

说明:下图为可以 & 不可以进行执行状态切换的场景

简而言之,下层软件为64位时,才能支持上层软件切换到32位

ARMv8体系结构基础01:ARMv8体系结构简介_第4张图片

2.3.4.2 执行状态切换规则

1. 不同的特权等级,可以使用不同的执行状态

2. 有2种方法可以改变PE的执行状态,

① reset

② 切换异常等级

3. 如上图所示,一定是下层软件是64位时,才能支持上层软件切换到32位,也就是说,只能通过异常陷入更高的异常等级,才能进行执行状态的切换

4. 例如在64位操作系统(EL1)上需要运行32位和64位应用程序(EL0),假设当前32位应用程序正在运行,那么他需要通过SVC指令或者接收到一个中断从而陷入到EL1的64位操作系统。此时操作系统可以进行任务调度,从而切换到64位的应用程序运行

5. 在处理中断时,从AArch32切换到AArch64;在中断返回时,从AArch64切换到AArch32

说明:由于EL3是最高的异常等级,无法再进入更高的异常等级,所以除了reset,没有办法切换EL3的特权等级

3 AArch64中的寄存器

3.1 通用寄存器

AArch64执行状态提高31个64位通用寄存器,分别是X0 ~ X30,这些寄存器在任何异常等级均可访问

ARMv8体系结构基础01:ARMv8体系结构简介_第5张图片

说明1:习惯用法

① X29作为栈帧指针,保存栈帧地址,作用类似X86体系结构中的EBP寄存器

② X30作为过程调用链接寄存器,保存当前过程的返回地址,作用类似ARMv7体系结构中的LR

说明2:使用W0 ~ W30可以访问通用寄存器的低32位

ARMv8体系结构基础01:ARMv8体系结构简介_第6张图片

对于通用寄存器低32位的操作,需要注意其对高32位的影响

① 读取Wn寄存器时,将忽略Xn寄存器的高32位

② 写入Wn寄存器时,会将Xn寄存器的高32位置零

作为对比,在X86体系结构中,通过AX等寄存器操作EAX等寄存器的低位时,高位不会被影响

3.2 特殊寄存器

ARMv8体系结构除了提供31个通用寄存器,还提供多个特殊寄存器

ARMv8体系结构基础01:ARMv8体系结构简介_第7张图片

3.2.1 零寄存器(Zero Register

1. XZR是64位零寄存器,WZR是32位零寄存器

2. 读取零寄存器返回0,写入零寄存器被忽略

3. 零寄存器可以在绝大多数指令中使用,且不需要使用MSR / MRS指令访问

说明:AArch64中并没有X31 / W31寄存器,大多数指令编码中的31号寄存器指的就是零寄存器。当然,还有很小一部分指令编码中的31号寄存器指的是栈寄存器SP

3.2.2 PC指针(Program Counter

1. PC指针指向当前运行指令的下一条指令地址

2. 程序中不能直接访问PC指针,只能通过跳转指令、异常进入和返回进行间接修改(这点和X86体系结构就很相似了啊)

3. PC指针需要4B对齐,如不对齐将产生PC alignment fault

说明:作为对比,在ARMv7体系结构中,通用寄存器R15作为PC,程序可以直接访问

3.2.3 栈指针(Stack PointerSP

1. ARMv8体系结构为每个异常等级都实现了一个栈指针SP_ELn,以异常等级为后缀

2. 当PE在某个异常等级处理异常时,可配置使用如下2个栈指针之一(通过PSTATE.SP配置),

① 所处理异常的target exception level对应的SP_ELn(默认情况)

② SP_EL0(注意,EL0是不会作为target exception level的,所以这不是默认情况,而是需要特殊配置的)

说明1:配置使用SP_EL0是在PE已经切换到targe exception level上进行的

说明2:即使异常处理没有发生异常等级切换,也需要处理上述栈指针的配置

例如PE当前在EL1运行,并且使用SP_EL0。此时如果发生异常,并且target exception level也是EL1,虽然异常等级不会切换,但是栈指针也会自动切换为SP_EL1。此时如果想继续使用SP_EL0,则仍需要设置PSTATE.SP

说明3:根据上述规则,就可以总结PE在不同异常等级可以使用的栈指针

ARMv8体系结构基础01:ARMv8体系结构简介_第8张图片

其中的t后缀表示thread,此时使用SP_EL0作为栈指针;h后缀表示handler,此时使用当前异常等级对应的栈指针

说明4:在Linux内核中,当从EL0陷入EL1时,使用SP_EL1作为当前栈指针。此时SP_EL0可以作为一个临时寄存器使用,Linux内核会使用该寄存器存放进程的task_struct结构指针

说明5:在程序中使用SP,表示当前使用的SP_ELn;而WSP表示当前使用的SP_ELn的低32位

说明6:大多数指令不能引用栈指针SP,但是一些算术运算指令可以访问SP指针

ADD SP, SP, #0x10

3.2.4 保存处理状态寄存器(Saved Process Status RegisterSPSR

1. ARMv8体系结构为每个可作为target exception level的异常等级都实现了一个SPSR_ELn,以异常等级为后缀

2. 当异常发生时,PSTATE的状态将被保存在target exception level的SPSR寄存器;当异常返回时,将使用的SPSR寄存器中的值恢复PSTATE

3. 保存异常发生时PSTATE状态的另一个作用,就是可以在异常处理时通过SPSR寄存器判断发生异常时的PE状态,例如发生异常时PE的异常等级和执行状态

说明1:SPSR寄存器

ARMv8体系结构基础01:ARMv8体系结构简介_第9张图片

SPSR寄存器保存的很多状态位与PSTATE中是相同的,我们在PSTATE寄存器章节进行说明。这里特别说明一下M[4]和M[3:0]的含义

① M[4]:记录异常发生时的执行状态,即PSTATE.nRW位。0表示AArch64执行状态,1表示AArch32执行状态

② M[3:0]:记录异常发生时的异常等级及其使用的栈

ARMv8体系结构基础01:ARMv8体系结构简介_第10张图片

  • M[3:2]标识发生异常时的异常等级
  • M[1]为保留位,需要置为0
  • M[0]标识栈指针SP的选择,0表示使用SP_EL0,1表示使用与异常等级对应对应的SP_ELn

说明2:不像栈指针SP的使用可配置,异常发生时只能使用与targe exception level相应的SPSR_ELn

3.2.5 异常链接寄存器(Exception Link RegisterELR

1. ARMv8体系结构为每个可作为target exception level的异常等级都实现了一个ELR_ELn,以异常等级为后缀

2. 当异常发生时,异常返回地址将被保存在target exception level的ELR寄存器;当异常返回时,将使用的ELR寄存器中的值恢复到PC寄存器

说明:和SPSR寄存器一样,异常发生时也只能使用与targe exception level相应的ELR_ELn

3.3 PSTATE寄存器

在ARMv7体系结构中,使用CPSR寄存器来表示当前处理器的状态。在ARMv8中,将PE的状态抽象为PSTATE。在实现上,则是一些列寄存器

3.3.1 PSTATE状态位

下面分组说明PSTATE状态位

3.3.1.1 条件标志位

ARMv8体系结构基础01:ARMv8体系结构简介_第11张图片

关于C位的讨论,详见下文

3.3.1.2 异常掩码标志位

ARMv8体系结构基础01:ARMv8体系结构简介_第12张图片

说明:NZCV标志位对于EL0可见,DAIF标志位需要经过配置对EL0才可见,其余标志位对EL0均不可见

3.3.1.3 运行状态控制位

ARMv8体系结构基础01:ARMv8体系结构简介_第13张图片

 

1. SS位:软件单步调试位

该位为1时,每条指令的运行都会产生单步异常

2. IL位:非法执行状态位

该位为1时,执行任何指令都会产生非法指令异常

3. nRW:当前执行状态位

0表示AArch64执行状态,1表示AArch32执行状态

4. EL:当前异常等级

PE复位时,PE被设置位实现的最高异常等级

5. SP:栈指针选择位

1表示使用与异常等级相应的SP_ELn,0表示使用SP_EL0

3.3.1.4 访问权限位

ARMv8体系结构基础01:ARMv8体系结构简介_第14张图片

关于访问权限位,与VMSA(Virtual Memory System Architecture)相关,此处只做简单说明

1. PAN(Privileged Access Never)

① ARMv8.1版本引入

② 如果PAN位为1,在EL1或EL2访问属于EL0的虚拟地址时,会触发访问权限错误;0表示不支持该功能

2. UAO(User Access Override)

① ARM8.2版本引入

② 如果UAO位为1,如果PE运行在EL1或EL2并且使用非特权的Load / Store指令,则内存访问权限由所在的异常等级决定,而不是EL0的访问权限;0表示不支持该功能

3. TCO(Tag Check Override)

① ARMv8.5版本引入

② 如果TCO为1,表示支持该功能;0表示不支持该功能

4. BTYPE(Branch target identification bit)

① ARMv8.5版本引入

3.3.2 PSTATE状态位的访问

ARMv8体系结构提供了一组特殊寄存器,用于访问PSTATE状态位

ARMv8体系结构基础01:ARMv8体系结构简介_第15张图片

说明1:由于用于访问PSTATE状态位的寄存器也是特殊寄存器,因此使用MRS / MSR指令访问,下图为需要使用MRS / MSR指令访问的特殊寄存器

ARMv8体系结构基础01:ARMv8体系结构简介_第16张图片

说明2:修改PSTATE状态的指令会影响PE的状态,因此在ARMv8体系结构中,对于修改PSTATE状态的指令,实现如下规则

① 对于修改PSTATE状态之前的指令,修改PSTATE状态的指令不可见

② 对于修改PSTATE状态之后的指令,修改PSTATE状态的指令可见

这就确保了在乱序执行的条件下,对PSTATE状态的修改效果与预期是一致的

3.3.3 条件标志C位的讨论

ARMv8体系结构中对条件标志C位的维护与X86体系结构有所不同,此处专门加以说明

3.3.3.1 疑惑的来源:SBC指令

SBC指令用于实现带借位的减法操作,下面是SBC指令的说明

ARMv8体系结构基础01:ARMv8体系结构简介_第17张图片

这里让我疑惑的是,此处减去的是C位取反,在X86体系结构中,当减法发生借位时,C位置1,此处显然规则是不同的

也就是说,对于如下指令,操作结果相当于 = - - 1 + C

SBC , , 

从中可以看出,在ARMv8体系结构中,对于减法操作,当发生算数上的借位时,C位为0;如果没有发生算数上的借位时,C位为1

3.3.3.2 解惑之旅:SUBS指令

为了验证上面的猜想,我们分析SUBS指令对C标志位的影响

ARMv8体系结构基础01:ARMv8体系结构简介_第18张图片

下图为SUBS指令的伪操作,可见SUBS指令的核心操作,是先将operand2取反,之后便调用AddWithCarry函数

ARMv8体系结构基础01:ARMv8体系结构简介_第19张图片

3.3.3.3 AddWithCarry函数分析

AddWithCarry函数是ARMv8体系结构中加减法的核心操作

ARMv8体系结构基础01:ARMv8体系结构简介_第20张图片

ARMv8体系结构基础01:ARMv8体系结构简介_第21张图片

UInt和SInt函数是被AddWithCarry函数调用的2个辅助函数,用于将一个二进制序列按无符号数和有符号数计算数值

ARMv8体系结构基础01:ARMv8体系结构简介_第22张图片

从AddWithCarry函数的实现可知,处理器在计算加法时,并不区分有符号数和无符号数,而是对两种情况均进行计算,并根据计算结果设置标志位

为了简化示例中的计算,我们假设有效位数为4位

1. 无算术运算借位示例

# 3 - 1

mov x1, #3

subs x0, x1, #1
operand1 = 3 = 0b0011

operand2 = NOT(1) = 0b1110



unsigned_sum = UInt(0b0011) + UInt(0b1110) + UInt(1)

             = 3 + 14 + 1 = 18 = 0b 1 0010 // 超出4位



signed_sum = SInt(0b0011) + SInt(0b1110) + UInt(1)

           = 3 + (-2) + 1 = 0b0010



 result = 0b0010 // 与注释中相同,unsigned_sum = signed_sum



UInt(result) != unsigned_sum,所以C = 1

SInt(result) == signed_sum,所以V = 0

由此可见,对于SUBS指令,当没有发生算术运算借位时,C标志位为1

2. 有算术运算借位示例

# 1 - 3

mov x1, #1

subs x0, x1, #3

 

operand1 = 1 = 0b0001

operand2 = NOT(3) = 0b1100



unsigned_sum = UInt(0b0001) + UInt(0b1100) + UInt(1)

             = 1 + 12 + 1 = 14 = 0b1110



signed_sum = SInt(0b0001) + SInt(0b1100) + UInt(1)

           = 1 + (-4) + 1 = -2 = 0b1110



 result = 0b1110 // 与注释中相同,unsigned_sum = signed_sum



UInt(result) == unsigned_sum,所以C = 0

SInt(result) == signed_sum,所以V = 0

由此可见,对于SUBS指令,当发生算术运算借位时,C标志位为0

由此就可以理解SBC指令中的伪操作了,即 = - - 1 + C,这就是的SBC指令的语义符合算术运算的结果,也就是当发生算术运算溢出时,应该多减1(此时C标志位为0)

3.3.3.4 C标志位使用示例

分析arch/arm64/include/barrier.h中array_index_mask_nospec函数的实现

ARMv8体系结构基础01:ARMv8体系结构简介_第23张图片

array_index_mask_nospec函数用于生成掩码,当idx < sz时,返回全f的掩码;当idx > =sz时,返回0

cmp %1, %2 ; 计算idx - sz的值,同时根据结果修改标志寄存器

sbc %0, xzr, xzr; 计算0 - 0 - 1 + C,如果cmp指令发生借位,则C=0

                ; 此时结果为0 - 0 - 1 + 0 = -1,即全f

补充:X86体系结构中C标志位的维护

调试如下X86汇编语言代码

mov ax, 1

mov bx, 2

sub ax, ax ; 1 - 2 = -1



mov ax, 0

sbb ax, ax ; 带借位减法,应该是0 - 0 - 1

① 执行sub ax, ax指令之后

ARMv8体系结构基础01:ARMv8体系结构简介_第24张图片

可见对于X86体系结构,当减法发生算术运算借位时,C标志位置为1

② 执行sbb ax, ax指令之后

ARMv8体系结构基础01:ARMv8体系结构简介_第25张图片

可见运算结果为-1,并产生新的借位

3.4 系统寄存器

1. ARMv8体系机构中定义了很多系统寄存器,通过访问和设置这些系统寄存器(通过MRS / MSR指令)来完成对处理器的功能设置

2. 在AArch64执行状态下,会根据不同的异常等级提供多个寄存器,命名规则如下,

_ELn,其中ELn标识了可访问该寄存器的最低异常等级

3. ARMv8体系结构支持如下7类系统寄存器

① 通用系统控制寄存器

② 调试寄存器

③ 性能监控寄存器

④ 活动监控寄存器

⑤ 统计扩展寄存器

⑥ 通用定时器寄存器

具体的系统寄存器等使用时加以说明,文档可参考ARMv8 ARM chapter D13

ARMv8体系结构基础01:ARMv8体系结构简介_第26张图片

4 ARMv8实现示例

ARMv8只是一种体系结构,基于该体系结构可以衍生出多种处理器内核

4.1 Cortex-A53 & Cortex-A57

Cortex-A53和Cortex-A57是基于ARMv8体系结构最早实现的2款处理器内核

ARMv8体系结构基础01:ARMv8体系结构简介_第27张图片

说明1:Cortex-A53 & Cortex-A57分别用于更新ARMv7体系结构中的Cortex-A7 & Cortex-A15

说明2:为了平衡性能和功率,可以在系统中混合使用Cortex-A53 & Cortex-A57,构成big.LITTLE结果

ARMv8体系结构基础01:ARMv8体系结构简介_第28张图片

4.2 Cortex-A72

本系列笔记使用的实验平台为树莓派4B+,其使用的处理器核心为Cortex-A72,其结构如下图所示

ARMv8体系结构基础01:ARMv8体系结构简介_第29张图片

5 其他内容

5.1 支持数据类型

ARMv8体系结构支持如下数据类型

1. 整数类型

Byte:8 bits

Halfword:16 bits

Word:32 bits

Doubleword:64 bits

Quadword:128 bits

其中Linux内核一般只支持到64 bits

2. 浮点类型

Half-precision / Single-precision / Double-precision / BFloat16

5.2 调试类型概述

ARMv8体系结构支持2种调试类型,

5.2.1 Self-hosted debug

1. 在这种模式下,由PE产生调试异常

2. 一般用于应用程序调试

5.2.2 External debug

1. 在这种模式下,debug evnet导致PE进入调试状态,此时PE由外部调试器控制

2. 一般用于操作系统调试

说明:绝大多数系统寄存器在EL0下不能访问

你可能感兴趣的:(计算机体系结构,计算机体系结构)