1.ARM工作状态
arm 支持大小端(默认小端 ,大端格式:高字节在低地址,低字节在高地址;小端格式:高字节在高地址,低字节在低地址;)、arm支持16bit thumb指令和32bit arm指令(默认arm指令),指令是16位与32位共存的。
2.ARM工作工作模式
不同 工作模式 下 可访问的寄存器和指令集有差异,长度不一样,或者是功能不一样,主要用于区分运行权限保护系统(由运行异常、中断或者软件主动触发切换模式)
工作模式分类(7种):
1、用户模式(Usr):用于正常执行程序;
2、快速中断模式(FIQ):用于高速数据传输;
3、外部中断模式(IRQ):用于通常的中断处理;
4、管理模式(svc):操作系统使用的保护模式;
5、数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于虚拟存储以及存储保护;
6、系统模式(sys):运行具有特权的操作系统任务;
7、未定义指令中止模式(und):当未定义的指令执行时进入该模式,可用于支持硬件。
注意:不是所有ARM架构的产品都是7种工作模式的
2.1.Arm的工作模式切换有两种方法:
被动切换:在arm运行的时候产生一些异常或者中断来自动进行模式切换
主动切换:通过软件改变,即软件设置寄存器来经行arm的模式切换,应为arm的工作模式都是可以通过相应寄存器的赋值来切换的。
Tips:当处理器运行在用户模式下,某些被保护的系统资源是不能被访问的。
除用户模式外,其余6种工作模式都属于特权模式;
特权模式中除了系统模式以外的其余5种模式称为异常模式;
大多数程序运行于用户模式;
进入特权模式是为了处理中断、异常、或者访问被保护的系统资源;-----保护机制
3.ARM 指令和 THUMB指令的关系:
THUMB 指令是 ARM 指令的子集,可以相互调用,只要遵循一定的调用规则
Thumb 指令 与 ARM 指令 的时间效率和空间效率关系为:
存储空间约为ARM代码的60%~70%
指令数比ARM代码多约30%~40%
存储器为32位时ARM代码比Thumb代码快约40%
存储器为16位时Thumb比ARM代码快约40~50%
使用Thumb代码,存储器的功耗会降低约30%
注:当处理器处于Thumb状态时发生异常(如IRQ、FIQ、Undef、Abort、SWI等),则异常处理返回时,自动切换到 Thumb 状态。ARM 处理器总是 从 ARM 工作状态开始执行的。因此,如果要在调试器重运行 Thumb 程序,必须为 该 Thumb 程序添加一个 ARM程序头,然后再切换到Thumb工作状态,调用该 Thumb程序。
3.1.Thumb与ARM状态切换
在实际系统中,内核状态需要经常的切换()来满足系统性能要求。具体的切换是通过 ,即 BX 指令来实现的。指令格式为:
Thumb 工作状态 BX Rn
ARM 工作状态 BX Rn
其中 Rn 可以是寄存器 R0 ~ R15 中的任意一个。指令可以通过将寄存器Rn的内容,拷贝到程序计数器 PC 来完成在 4GB地址空间中的绝对跳转,如果操作数寄存器的状态位 Bit0 = 0,则进入 ARM 工作状态;如果 Bit0 = 1,则进入 Thumb 工作状态。
ARM 处理器在两种工作状态之间可以切换,切换不影响处理器的模式或寄存器的内容。
4.寄存器
Arm 处理器总共有37个寄存器,其可以分为以下 2 类:
看图就可以算寄存器数量了,要看ARM指令的,不要看Thumb指令的。
所谓不分组就是在七种模式下的任意一种模式都访问同一个物理寄存器地址。就是不分组寄存器没有特权模式,任意一种模式都可以使用未分组寄存器。
5.ARM框架的寄存器解析
未分组寄存器:R0 - R7 R15 cpsr,cpu 在任何模式下看到的 这几个寄存器都是一样的。在所有的运行模式下,未分组寄存器都指向同一个物理寄存器,他们未被系统用作特殊的用途,因此,在中断或异常处理进行运行模式转换时,由于不同的处理器运行模式均使用相同的物理寄存器,可能会造成寄存器中数据的破坏,这一点在进行程序设计时应引起注意。分组寄存器 R8 - R14 在不同模式下看到的这几个寄存器是不一样的。
5.1.寄存器功能说明 5.1.1寄存器分组说明
1.未分组寄存器 R0 ~ R7,共 8 个。在所有的运行模式下都使用同一个物理寄存器,它们未被系统用作特殊的用途。
2.分组寄存器 R8 ~ R12,R13 ~ R14
R8 ~ R12:(总共10个)
每次所访问的物理寄存器与处理器当前的运行模式有关,R8~R12:每个寄存器对应两个不同的物理寄存器
当使用fiq模式时,访问寄存器~,当使用除fiq模式以外的其他模式时,访问寄存器~。
其中 FIQ 模式有单独的一组 R8 ~ R12,共5个;(FIQ ( 快速中断模式 )时访问寄存器 ~ )
另外 6 种模式共用一组 R8 ~ R12,共5个;(当使用除 FIQ 模式以外的其他模式时,访问寄存器 R8 ~ R12)
R13 ~ R14:(总共12个 )
其中 USR 和 SYS 模式(表格的第一列)共用一组 R13 ~ R14 共2个,
另外 5 种模式下各有独自的一组 R13 ~ R14,并采用以下记号来区分不同的物理寄存器,分别
为 fiq、irq、svc、abt、und。共10个。(mode为以下几种之一:usr、fiq、irq、svc、abt、und。)
i. R13 在 ARM 指令中常用作堆栈指针 SP
特别注意:由于每一种模式都有自己的 R13,所以我们在自己初始化的时候一般都要初始化每种模式下的R13,使其指向该运行模式的栈空间。
ii. R14 称为子程序链接寄存器 LR (Link )
有两个特殊功能,
一种是每一种模式下都可以用于保存函数的返回地址,
另外就是异常处理后的返回地址,如中断处理之后的跳转
3. PC 指针( R15 )
R15 用作程序计数器 ( PC ),对应一个物理寄存器,由于 ARM 体系结构采用了多级流水线技术
对于 ARM 指令集而言,PC 总是指向当前指令的下两条指令的地址,可以通过向 pc 赋值,来控制程序跳转。即 PC 的值为当前指令的地址值加8个字节。(这里和我们正常学习的不一样,正常都是PC指向下一条指令,也就是地址值加4字节)。
4. CPSR (1个状态寄存器。CPSR表示:当前程序状态寄存器)-----重点
CPSR寄存器是32位寄存器。
所以我们只要研究控制位和条件位即可。
5. SPSR (5 个 备份状态寄存器)
SPSR(备份的程序状态寄存器)
SPSR除 usr、sys 外,对应用于异常保护的 CPSR 的备份,异常时,保存CPSR值,异常退出时,将该值恢复到CPSR,以保证程序的正常运行,每一中异常运行模式(除usr和sys)有各自的物理寄存器。
5.1.2.寄存器的作用
0 - r3 : 用作传入函数参数,传出函数返回值。在子程序调用之间,可以将 r0-r3 用于任何用途。被调用函数在返回之前不必恢复 r0-r3。如果调用函数需要再次使用 r0-r3 的内容,则它必须保留这些内容。
r4 - r11 : 被用来存放函数的局部变量。如果被调用函数使用了这些寄存器,它在返回之前必须恢复这些寄存器的值。
r12 :是内部调用暂时寄存器 ip。它在过程链接胶合代码(例如,交互操作胶合代码)中用于此角色。在过程调用之间,可以将它用于任何用途。被调用函数在返回之前不必恢复 r12。
r13 : 是栈指针 sp。它不能用于任何其它用途。sp 中存放的值在退出被调用函数时必须与进入时的值相同。
r14 : 是链接寄存器 lr。如果您保存了返回地址,则可以在调用之间将 r14 用于其它用途,程序返回时要恢复
r15 : 是程序计数器 PC。它不能用于任何其它用途。
注意:在中断程序中,所有的寄存器都必须保护,编译器会自动保护 R4~R11
寄存器编号可选名字ATPCS寄存器用法
R0~R3
A1~A4
参数寄存器,在调用函数时,用来存放前4个函数参数和返回值,多出的存堆栈中。(易失的)
R4~R8
V1~V5
通用变量寄存器。(非易失性的)
R9
V6 sb
通用变量寄存器。在与读/写位置无关的编译情况下,用作基址寄存器。(非易失性的)
R10
V7 sl
通用变量寄存器。在使用堆栈边界检查的编译情况下,R10保存堆栈边界的地址。(非易失性的)
R11
V8 fp
通用变量寄存器。在使用结构指针的情况下,必须保存这个寄存器中调用函数的变量值。(非易失性的)
R12
Ip
通用临时过渡寄存器(易失的)
R13
堆栈指针,指向满递减堆栈
R14
lr
链接寄存器,在函数调用时用以保存返回地址
R15
pc
程序计数器
5.1.3.小结
37个寄存器是指通用寄存器和一些状态寄存器,这是 ARM 架构定义好的寄存器,事实上 ARMv7 已经不止这些寄存器了,37个寄存器是 ARMv6 以前的架构,典型的就是基于 的 ARM9 有这么多寄存器,之后 ARM 引入了 以及虚拟化就又引入了一些 寄存器。现在到了 ARMv8,通用寄存器又不一样了,具体可以看 ARM 的 spec。
6.ARM 64 经常用到的汇编指令
MOV X1,X0 ;将寄存器X0的值传送到寄存器X1
ADD X0,X1,X2 ;寄存器X1和X2的值相加后传送到X0
SUB X0,X1,X2 ;寄存器X1和X2的值相减后传送到X0
AND X0,X0,#0xF ; X0的值与0xF相位与后的值传送到X0
ORR X0,X0,#9 ; X0的值与9相位或后的值传送到X0
EOR X0,X0,#0xF ; X0的值与0xF相异或后的值传送到X0
LDR X5,[X6,#0x08] ;X6寄存器加0x08的和的地址值内的数据传送到X5
STR X0, [SP, #0x8] ;X0寄存器的数据传送到SP+0x8地址值指向的存储空间
STP x29, x30, [sp, #0x10] ;入栈指令
LDP x29, x30, [sp, #0x10] ;出栈指令
CBZ ;比较(),如果结果为零(Zero)就转移(只能跳到后面的指令)
CBNZ ;比较,如果结果非零(Non Zero)就转移(只能跳到后面的指令)
CMP ;比较指令,相当于SUBS,影响程序状态寄存器CPSR
B/BL ;绝对跳转#imm, 返回地址保存到LR(X30)
RET ;子程序返回指令,返回地址默认保存在LR(X30)
其中MOV指令只能用于寄存器之间传值,寄存器和内存之间传值通过LDR和STR。b是跳转指令
阿里社区也有一个很不错的整理,这里附上链接。
6.1.指令条件
ARM指令所有指令都是带有条件的,默认是AL即无条件执行,当指令带有默认条件时不需要明确写出。
操作码条件码助记符标志含义
0000
EQ
Z=1
相等
0001
NE(Not Equal)
Z=0
不相等
0010
CS/HS(Carry Set/High or Same)
C=1
无符号数大于或等于
0011
CC/LO(Carry Clear/LOwer)
C=0
无符号数小于
0100
MI(MInus)
N=1
负数
0101
PL(PLus)
N=0
正数或零
0110
VS( set)
V=1
溢出
0111
VC( clear)
V=0
没有溢出
1000
HI(HIgh)
C=1,Z=0
无符号数大于
1001
LS(Lower or Same)
C=0,Z=1
无符号数小于或等于
1010
GE( or Equal)
N=V
有符号数大于或等于
1011
LT(Less Than)
N!=V
有符号数小于
1100
GT( Than)
Z=0,N=V
有符号数大于
1101
LE(Less or Equal)
Z=1,N!=V
有符号数小于或等于
1110
AL
任何
无条件执行(默认)
1111
NV
任何
从不执行
参考链接:
ARM 寄存器 详解_擒贼先擒王的博客-CSDN博客_用于子程序或函数调用时保存返回地址、减少内存访问次数的寄存器是