“架构”(Architecture)指的是功能规范,ARM架构即是ARM处理器的功能规范,包括以下主要内容:
“架构”没有直接说明如何构建处理器并工作,它只是提供了一种软件和硬件之间行为规范,具体的处理器的构建和设计称为“微架构”Micro-Architecture,微架构包括:
ARM提供了三种架构概要:
处理器的构建和设计称为“微架构”,微架构定义处理器的工作原理,包括:流水线的长度和布局,缓存的数量和大小,单个指令的周期数以及其它可选特性。
ARMv7-A架构是32位处理器架构,也是load/store架构,即数据处理指令操作在通用寄存器完成,只有load/store指令可以访问内存。此外ARM指令集还有一大特点,就是ARM指令集几乎所有的指令都可以增加条件码。
ARM指令集可以归为一下四类:
ARMv7架构支持安全扩展,如果使能了安全扩展,ARMv7-A架构分为安全模式(Secure State)和非安全模式(Non-secure State)两个世界。
在非安全模式下,存在三种运行特权PL0,PL1和PL2(privilege level)。
特权等级 | 描述 |
---|---|
PL0 | PL0运行在用户模式(User),用于运行应用程序。该模式程序受限访问系统资源。对应Linux用户态。 |
PL1 | PL1运行非用户模式和Hyp模式外的所有模式。Linux内核运行在PL1。包含了ARMv6架构中的System,SVC,FIQ,IRQ,UNDEF及Abort模式。此外,安全模式中的Montior也运行在PL1等级,管理安全模式和非安全模式的切换。 |
PL2 | PL2用于虚拟化。虚拟化超级管理程序(Hypervisor)运行在 PL2。 |
ARMv7-A 处理器有 16 个通用寄存器:R0~R15,其中:
对于每种特权等级访问系统资源的权限不一样,而处理器又有几种模式,每种模式对应的特权等级有一定区别;每一种处理器模式对应的寄存器也有一定区别:
ARMv7-A 还有一个特殊寄存器叫:程序状态寄存器 CPSR(Current Program Status Register),再进入异常之前,当前的 CPSR 被保存到 SPSR (Saved Program Status Register)中;
CPRS 在用户层叫做 APSR,APSR 只是 CPSR 寄存器中被截取的一部分,因为在用户层,并不是所有的 CPSR 的位都可以访问;
Field | 作用 |
---|---|
N | ALU返回运算结果是否为负数 |
Z | ALU返回运算结果是否为0 |
C | ALU运算是否发生进位 |
V | ALU运算是否发生溢出 |
Q | cumulative saturation |
J | ARM是否处于 Jazelle 状态 |
E | 控制 load/store 字节序,E=1表示大端模式,E=0表示小端模式 |
A | disables asynchronous aborts,User模式不能操作 |
I | 使能/禁能 IRQ,User模式不能操作,I=1表示禁止 IRQ,I=0表示使能 IRQ |
F | 使能/禁能 FIQ,User模式不能操作,F=1表示禁止 FIQ,I=0表示使能 FIQ |
T | ARM和Thumb状态标志位 |
GE | 用于某些SIMD(Single Instruction, Multiple Data)指令 |
M[4:0] | 处理器模式:FIQ,IRQ,ABT,SVC,UND,MON,HYP。User模式不能操作 |
IT[7:0] | IT7:2:和IT1:0一起组成IT[7:0],表示IF-THEN指令的执行状态 |
[28-31]:条件码
M[4:0]:处理器模式的Encoding
Armv8-A架构是针对应用框架的最新一代Arm架构。ARMv8架构继承了ARMv7与之前处理器技术的基础,除了对现有的16/32bit的Thumb2指令支持外,也向前兼容了现有的A32(ARM 32bit)指令集,基于64bit的AArch64架构,除了新增A64(ARM 64bit)指令集外,也扩充了现有的A32(ARM 32bit)和T32(Thumb2 32bit)指令集,另外还新增加了CRYPTO(加密)模块支持。
为了向前兼容Armv7,Armv8-A支持两种Execution State,分别是AArch32和AArch64,两种Execution State有如下区别:
AArch32 | AArch64 |
---|---|
提供13个32bit通用寄存器R0-R12,一个32bit PC指针 (R15)、堆栈指针SP (R13)、链接寄存器LR (R14) | 提供31个64bit通用寄存器X0-X30(W0-W30),其中X30是程序链接寄存器LR |
提供一个32bit异常链接寄存器ELR,用于Hyp mode下的异常返回 | 提供一个64bit PC指针、堆栈指针SPx 、异常链接寄存器ELRx |
提供32个64bit SIMD向量和标量floating-point支持 | 提供32个128bit SIMD向量和标量floating-point支持 |
提供两个指令集A32(32bit)、T32(16/32bit) | 定义ARMv8异常等级ELx(x<4),x越大等级越高,权限越大 |
兼容ARMv7的异常模型 | 定义一组PSTATE,用以保存PE(Processing Element)状态 |
协处理器只支持CP10\CP11\CP14\CP15 | 没有协处理器概念 |
通用寄存器
在ARM64架构下,CPU提供了33个寄存器, 其中前31个(0~30)是通用寄存器 (general-purpose integer registers)。
寄存器 | 说明 |
---|---|
X0寄存器 | 用来保存返回值(或传参) |
X1 ~ X7 寄存器 | 用来保存函数的传参 |
X8寄存器 | 也可以用来保存返回值 |
X9 ~ X28寄存器 | 一般寄存器,无特殊用途 |
X29(FP)寄存器 | 用来保存栈底地址 |
X30 (LR)寄存器 | 链接寄存器,用来保存返回地址 |
每个AArch64 64位通用寄存器X0-X30都有一个对应的32位寄存器,Wn寄存器是Xn寄存器的低32位,读Wn寄存器时会保持Xn寄存器的高32位不变,如果写W寄存器时,会将X寄存器的高32位设为0。
特殊寄存器
除了31个通用寄存器,还有几个特殊的寄存器:
1、zero register:写操作被忽略,读操作都返回0;
2、SP/WSP:当前栈指针;
3、PC program counter:ARMv7指令集使用通用寄存器R15作为PC,直接操作PC可以做一些机智的编程操作,但是ARMv8不能直接进入PC,这使返回更好预测,并且使ABI规范更加简单;
4、ELR / SPSR:当armV8执行在AArch64,每个ELn异常返回状态取决于ELR和SPSR
ELR: exception link register 保存exception返回地址
SPSR: saved processor state register 执行exception前保存当前的processor state, 执行exception完返回时restore
在ARMv8中,如果异常发生在EL1,就使用SPSR_EL1,如果发生在EL2, 使用SPSR_EL2,如果发生在EL3, SPSR_EL3使用
ELR 和SPSR时成对的,其和对应的ELn相关
5、SP 每个 exception level 都有对应的 SP:
Armv8有32个 128bit的浮点寄存器 V0-V31. 这32个寄存器用来处理标量浮点预算和NEON指令。
A64指令的编码是固定的32bits;A32指令的编码也是固定的32bits;T32指令编码是可变长的16bits、32bits。
ARM指令使用的是 三地址码 , 它的格式如下:
{} {S} , ,
opcode:操作码,也就是助记符,操作码,也就是助记符,说明指令需要执行的操作类型
cond:指令执行条件码,在编码中占4bit,0b0000 -0b1110
S:条件码设置项,决定本次指令执行是否影响PSTATE寄存器响应状态位值
Rd:目标寄存器,A64指令可以选择X0-X30 or W0-W30
Rn:第一个操作数的寄存器,和Rd一样,不同指令有不同要求
shifter_operand:第二个操作数,可以是立即数,寄存器Rm和寄存器移位方式(Rm,#shit)
指令分类
常见指令
add:将某一寄存器的值和另一寄存器的值 相加 并将结果保存在另一寄存器中
add x0, x0, #1 ; 将寄存器 x0 的值和常量 1 相加后保存在寄存器 x0 中
add x0, x1, x2 ; 将寄存器 x1 和 x2 的值相加后保存到寄存器 x0 中
add x0, x1, [x2] ; 将寄存器 x1 的值加上寄存器 x2 的值作为地址,再取该内存地址的内容放入寄存器 x0 中
mov:把一个寄存器的值(要能用立即数表示)赋给另一个寄存器,或者将一个常量赋给寄存器,将后边的量赋给前边的量
mov R1, R0 ; 将寄存器R0的值传送到寄存器R1
mov PC, R14 ; 将寄存器R14的值传送到PC,常用于子程序返回
mov R1, R0, LSL#3 ; 将寄存器R0的值左移3位后传送到R1(即乘8)
movs PC, R14 ; 将寄存器R14的值传送到PC中,返回到调用代码并恢复标志位
sub:用于把操作数1减去操作数2,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令可用于有符号数或无符号数的减法运算
sub R0, R1, R2 ;R0 = R1 - R2
sub R0, R1, #256 ;R0 = R1 - 256
sub R0, R2, R3, LSL#1 ;R0 = R2 - (R3 << 1)
异常模型
Armv8有四种Exception Level,分别是EL0,EL1,EL2,EL3
Exception | Level |
---|---|
EL0 | Application |
EL1 | Linux kernel- OS |
EL2 | Hypervisor |
EL3 | Secure Monitor |
Security | |
Non-secure | Non-secure EL0/EL1/EL2, 只能访问Non-secure memory |
Secure | Secure EL0/EL1/EL3, 可以访问Non-secure memory & Secure memory |
注意处理器异常等级有如下规则: