介绍
- aarch64是 ARM 架构的 64 位版本,它是 ARMv8 架构的一部分,被设计用来提供更高的性能和更大的地址空间,同时保持与 32 位 ARM 架构的兼容性。
- AArch64 是 ARMv8 的 64 位指令集架构(ISA),它提供了丰富的指令集来支持高性能计算。
- Armv8-A支持三种指令集:A32、T32和A64;在AArch64执行状态下执行时使用A64指令集。它是一个固定长度的32位指令集,名称中的64指的是AArch64执行状态对该指令的使用。它不是指内存中指令的大小。A32和T32指令集也分别被称为Arm和Thumb。
- 特点:
- 64位寄存器:提供了更多的寄存器,每个寄存器都是 64 位宽。
- 更大的地址空间:支持超过 4GB 的内存地址空间。
- 改进的指令集:包括新的指令和对现有指令的扩展,以提高性能和效率。
- SIMD 扩展:高级 SIMD ( neon) 扩展,提供对单指令多数据(SIMD)操作的支持,增强了图形和多媒体应用的性能。
- 虚拟化支持:提供了硬件虚拟化功能,使得 AArch64 架构的处理器可以更有效地运行虚拟机。
- 节能特性:包括多种节能技术,如动态调频和电压调整(DVFS)。
- 安全性增强:包括安全启动和加密功能,提高了系统的安全性。
寄存器
- 寄存器:
- 寄存器是中央处理器(CPU)内部的一小部分高速存储资源,用于快速访问和处理数据。它们在计算机体系结构中起着至关重要的作用。
- 寄存器(Register)是 CPU 内部的存储单元。可以用来暂存程序指令,数据和内存地址。因为存在于 CPU 内部,所以它的读写速度要比内存快得多。
- 在寄存器和内存之间,还有一层存储介质叫缓存(Cache)。缓存也在 CPU 内部,访问速度比寄存器慢,比内存快。对于程序而言缓存是透明的,不可操作。
- 寄存器与内存关系:
- 寄存器和内存是计算机体系结构中的两种基本存储资源,它们在程序执行和数据处理中扮演着不同但互补的角色。
- 寄存器是 CPU 内部的一小部分高速存储资源,其访问速度远远快于主存(RAM)。内存则作为计算机的主要存储介质,容量较大但访问速度较慢。
- 寄存器用于暂存指令、数据和地址,供 CPU 快速处理。内存则用于存储程序的指令代码、大量数据和中间计算结果。
- 寄存器可以被 CPU 直接访问,而内存则需要通过地址总线间接访问。
- 寄存器的数据宽度通常是固定的,如 32 位或 64 位,而内存可以存储任意大小的数据。
- 寄存器和内存之间的数据交换是通过数据总线进行的。CPU 使用 LOAD 和 STORE 指令将数据从内存加载到寄存器,或从寄存器存储到内存。
- 寄存器作为 CPU 内部的快速存储资源,经常用于暂存从内存中读取的数据或指令,以及待写入内存的数据;所以寄存器和内存之间的关系就是传递这几种类型的数据,以便于
CPU 进行计算。
- 寄存器与汇编语言:
- 汇编语言是一种用于电子计算机、微处理器、和其他可编程设备低级编程的编程语言。它是机器语言的文本表示形式,几乎与机器码一一对应,但提供了一些助记符来增强可读性。
- 汇编语言提供了直接操作 CPU 寄存器的能力。程序员可以通过汇编指令来控制寄存器中的数据,进行加载、存储、算术运算、逻辑运算等操作。
- 汇编语言中的每条指令通常都直接映射到 CPU 的指令集架构上。这意味着汇编语言中的指令直接体现了 CPU 能够对寄存器执行的操作。
- 在汇编层面,函数参数和返回值通常通过寄存器传递,以减少内存访问的开销。
- 不同的 CPU 架构有不同的寄存器集和专用寄存器,汇编语言允许程序员利用这些特性来编写高效的代码。
- 通用寄存器:
- 通用寄存器是一组用于存储数据和地址的寄存器,它们在处理程序中扮演着核心角色。
- 作用
- 通用寄存器用于存储临时数据、计算结果和变量;
- 在函数调用时,前几个参数通常通过 X0 到 X7 寄存器传递。返回值通常存储在 X0 寄存器中;
- 通用寄存器参与算术(如加、减、乘、除)和逻辑(如 AND、OR、NOT、XOR)运算;
- 寄存器用于提供内存访问指令中的基地址、偏移量或索引;
- 某些通用寄存器(如 X8 到 X17)可以作为调用者保存的寄存器,在函数调用中保持不变,或用于存储局部变量;
- 虽然 AArch64 没有单独的状态寄存器,但通用寄存器可以用于存储和传递状态信息,如条件标志;
- 通用寄存器用于存储系统调用的编号和参数,以及在异常或中断处理中保存上下文;
- 大多数A64指令都在寄存器上操作。AArch64架构提供了31个通用寄存器。每个寄存器都可以用作64位X寄存器(X0~X30)或32位W寄存器(W0~W30)。这是查看同一寄存器的两种不同方式。例如,下边这个寄存器图显示W0是X0的低32位,W1是X1的低32位。
- 每个通用寄存器都是 64 位宽,这意味着它们可以存储 64 位(8 字节)的整数数据。
- x0 - x30 是31个通用整形寄存器。每个寄存器可以存取一个64位大小的数。 当使用 x0 - x30 访问时,它就是一个64位的数。当使用 w0 - w30 访问时,访问的是这些寄存器的低32位。
- 对于数据处理指令,X或W的选择决定了操作的size。使用X寄存器将导致64位的计算,使用W寄存器将导致32位的计算。
- 32位整数加法:
ADD W0, W1, W2
- 64位整数加法:
ADD X0, X1, X2
- 其他寄存器:
- 零寄存器:XZR和WZR,总是读取为0并忽略写入。XZR是64位的零寄存器,WZR是32位的零寄存器。
- 栈指针(stack pointer,SP)寄存器:栈指针寄存器是实现程序的运行时栈管理的关键组件,对于维护程序的执行流程和状态管理至关重要。
- 链接寄存器(Link Register,LR):在计算机体系结构中是一个专用寄存器,主要用于存储函数调用的返回地址;在 AArch64 架构中,LR 通常被命名为 X30,而在其他架构中,它可能是一个单独的寄存器。
- 程序计数器(PC):是 cpu 内部一个特殊的寄存器,程序计数器是 CPU 执行指令的基础,它确保了指令能够按正确的顺序被取出和执行。
- 浮点寄存器:
- AArch64架构引入了SIMD(Single Instruction, Multiple Data)操作,通过矢量寄存器(Vector Registers)来支持高级的浮点运算和数据处理;
- AArch64提供了32个128位宽的浮点寄存器,编号从V0~V31;
- 每个浮点寄存器都是128位宽,足以存储两个64位的双精度浮点数或四个32位的单精度浮点数;
- NEON 寄存器:
- 128 位宽,与浮点寄存器重叠使用,编号从 Q0 ~ Q31;
- AArch64 架构的 SIMD 指令集称为 NEON。NEON 寄存器(Q0 到 Q31)实际上是浮点寄存器的另一种视图,用于访问 SIMD 功能。
- 在 AArch64(ARMv8-A)架构中,浮点寄存器和 NEON 寄存器实际上是同一组寄存器,它们共用相同的物理寄存器集合,但是以不同的方式使用和访问。
- AArch64 提供了一组共用的 128 位寄存器,用于浮点和 SIMD(单指令多数据)操作。
- NEON 是 ARM 的 SIMD 指令集,用于处理向量运算。NEON 寄存器用于 SIMD 操作,可以对多个数据元素执行并行操作。
- SVE 寄存器:
- 在 AArch64 架构中,Scalable Vector Extension(SVE)引入了新的寄存器类型,这些寄存器与传统的通用寄存器和浮点寄存器不同。
- SVE引入了可变长度的矢量寄存器,这些寄存器可以从128位扩展到2048位,以适应不同的计算需求;
- SVE寄存器(Z0-Z31)在低位与AArch64的SIMD&FP寄存器(V0-V31)共享硬件资源,但SVE提供了更高级的SIMD功能和更大的数据处理能力;
- 在 ARMv9 架构上发布的 SVE2 是 SVE 指令集的超集和扩展,提供了更多的指令和特性。
- 系统寄存器:
- 控制 CPU 的各种系统级功能和行为;
- 系统寄存器不能直接用于数据处理或load/store指令。相反,需要将系统寄存器的内容读入通用寄存器X,对其进行操作,然后将其写回系统寄存器。有两个专门用来访问系统寄存器的指令MRS和MSR。
- 主要的系统寄存器:
- 系统控制寄存器:SCTLR_ELx,用于控制系统行为,如缓存、页表遍历等;
- 内存管理寄存器:TTBR0_ELx / TTBR1_ELx、TCR_ELx、VTTBR_EL2;
- 异常链接寄存器:ELR_ELx;
- 保存处理状态寄存器:SPSR_ELx;
- 中断控制寄存器:DAIF、ICC_*;
- 性能计数器寄存器:
- 电源管理控制寄存器:
- 虚拟化控制寄存器:
- 安全控制寄存器:SCR_EL3
- 调试和跟踪控制寄存器
- 系统寄存器访问控制
- 浮点控制寄存器:FPCR
- 系统寄存器命名:系统寄存器通常带有 _ELx 后缀,其中 x 表示异常级别(如 EL1、EL2、EL3)
数据处理指令
- 算术运算指令:
- 加法:ADD、ADDS、ADDG
- 减法:SUB、SUBS、SUBP、SUBG、SUBPS 等
- 乘法:MUL、MADD、MNEG等
- 除法:UDIV、SDIV等
- 逻辑运算指令:
- 逻辑与:AND
- 逻辑或:ORR
- 逻辑异或:EOR
- 位清除:BIC
- 移位运算指令:
- 逻辑左移:LSL
- 逻辑右移:LSR
- 算术右移:ASR
- 循环右移:ROR
- 比较指令:
- 比较:CMP
- 负向比较:CMN
- 浮点操作指令:浮点操作遵循与整数数据处理指令相同的格式,并使用浮点寄存器。与整数数据处理指令一样,操作的大小决定了所使用的寄存器的大小。浮点指令的operation总是以 F 开头。
- 浮点加法:FADD
- 浮点减法:FSUB
- 浮点乘法:FMUL
- 浮点除法:FDIV
- 浮点平方根:FSQRT
数据加载与存储指令
在 AArch64 架构中,数据加载与存储指令用于在处理器和内存之间移动数据。
- 加载寄存器:
- LDR: 从内存中加载数据到寄存器。它可以用于加载字节、半字、字或双字数据。
- 存储寄存器:
- STR: 将数据从寄存器存储到内存。与 LDR 相对应,它也可以用于存储不同大小的数据。
c++ 中使用汇编方法
- 内联汇编
- 外部汇编文件
- 内联汇编与 c++混用
- 使用宏定义