文章目录
第一章 ARM概述及其基本编程模型
1.1 ARM技术的应用领域与其特点
1.2 ARM体系结构的版本和命名方法
ARM体系结构的版本
3.版本3
- 处理器的地址扩展到32位
- 当前的程序状态信息从原来的R15寄存器移到一个新的寄存器CPSR(Current Program Status Register)。
- 增加SPSR(Saved Program Status Register),用于在程序异常中断程序时,保存被中断的程序状态。
- 增加了指令MRS和MSR,用于访问CPSR和SPSR。
4.版本4
- 增加了T变种,可以从处理器状态切换到Thumb状态,在该状态下指令集是16位的Thumb指令。
- 增加了处理器的特权模式。在该模式下,使用的是用户模式下的寄存器。
5.版本5
- 增加了前导零计数指令:使整数除法和中断优先级排队操作更为有效。
- 增加软件断点指令
6.版本6
增加SIMD功能。SIMD功能扩展为包括音频/视频在内的应用系统提供了优化功能,可以使
ARM体系的变种
thumb指令集(T变种)
Thumb指令集是将ARM指令集的一个子集重新编码而形成的一个指令集。ARM指令长度为32位,Thumb指令长度为16位。Thumb指令集可以得到密度更高的代码。
长乘法指令(M变种)
增加两条长乘法操作的ARM指令
- 实现32位整数乘以32位整数
- 实现32位整数乘以32位整数+32位整数
增强型DSP指令(E变种)
增强处理器对DSP算法的处理性能
Java加速器(J变种)
java加速功能
ARM媒体功能扩展(SIMD变种)
ARM媒体功能扩展为嵌入式应用系统提供了高性能的音频/视频处理技术。
ARM的SIMD媒体功能扩展为包括音频/视频在内的应用系统提供了优化功能,可以使音频/视频处理性能提高4倍
1.3 ARM处理器系列
- ARM7
- ARM9
- ARM9E
- ARM10E
- SecurCore
1.3 ARM处理器系列
ARM处理器共有7种运行模式
处理器模式 | 描述 |
---|---|
用户模式(User,usr) | 正常(用户)程序执行的模式 |
快速中断模式(FIQ,fiq) | 用于高速数据传输和通道处理 |
外部中断模式(IRQ,irq) | 用于通常的中断处理 |
管理模式(Supervisor,sve) | CPU上电后默认模式,主要用来做系统的初始化 供操作系统使用的一种保护模式 |
数据访问中止模式(Abort,abt) | 用于虚拟存储及存储保护 |
未定义指令中止模式(Undefined,und) | 用于支持通过软件仿真硬件的协处理器 |
系统模式(System,sys) | 用于运行特权级的操作系统任务 |
- 特权模式下,程序可以访问所有的系统资源,也可以任意地进行处理器模式的切换。
- 处理器模式的切换 by
- 软件控制
- 外部中断或异常处理
- 大多数的用户程序运行在用户模式下,不能访问一些受操作系统保护的系统资源,应用程序也不能直接进行处理器模式的切换。当需要进行处理器模式切换时,应用程序可以产生异常处理,在异常处理过程中进行处理器模式的切换。
- 系统模式不是通过异常过程进入的,它和用户模式具有完全一样的寄存器。它主要供操作系统任务使用。通常操作系统的任务需要访问所有的系统资源,同时该任务仍然使用用户模式的寄存器组,而不是使用异常模式下相应的寄存器组,这样可以保证当异常中断发生时任务状态不被破坏。
1.5 ARM寄存器介绍
ARM处理器有37个寄存器,其中包括
- 31个通用寄存器 [ 32位寄存器 ] 。
- 6个状态寄存器
用户模式 | 系统模式 | 管理模式 | 中止模式 | 未定义模式 | 外部中断模式 | 快速中断模式 |
---|---|---|---|---|---|---|
R0 | R0 | R0 | R0 | R0 | R0 | R0 |
R1 | R1 | R1 | R1 | R1 | R1 | R1 |
R2 | R2 | R2 | R2 | R2 | R2 | R2 |
R3 | R3 | R3 | R3 | R3 | R3 | R3 |
R4 | R4 | R4 | R4 | R4 | R4 | R4 |
R5 | R5 | R5 | R5 | R5 | R5 | R5 |
R6 | R6 | R6 | R6 | R6 | R6 | R6 |
R7 | R7 | R7 | R7 | R7 | R7 | R7 |
R8 | R8 | R8 | R8 | R8 | R8 | R8_fiq |
R9 | R9 | R9 | R9 | R9 | R9 | R9_fiq |
R10 | R10 | R10 | R10 | R10 | R10 | R10_fiq |
R11 | R11 | R11 | R11 | R11 | R11 | R11_fiq |
R12 | R12 | R12 | R12 | R12 | R12 | R12_fiq |
R13 | R13 | R13_svc | R13_abt | R13_und | R13_irq | R13_fiq |
R14 | R14 | R14_svc | R14_abt | R14_und | R14_irq | R14_fiq |
PC | PC | PC | PC | PC | PC | PC |
CPSR | CPSR | CPSR | CPSR | CPSR | CPSR | CPSR |
SPSR_svc | SPSR_abt | SPSR_und | SPSR_irq | SPSR_fiq |
1.5.1 通用寄存器
通用寄存器可以分为 3 类
- 未备份寄存器(Unbanked Registers),R0~R7。
- 备份寄存器(Banked Regsiter),包括 R8~R14。
- 程序计数器 PC,即R15。
未备份寄存器 R0~R7
在所有的处理器模式下指的都是同一个物理寄存器。
在异常中断造成处理器模式切换时,由于不同的处理器模式使用相同的物理寄存器,可能造成寄存器中数据被破坏。
未备份寄存器没有被系统用于特别的用途,任何可采用通用寄存器的应用场合都可以使用未备份寄存器。
备份寄存器 R8~R14
- R8~R12
- 每个寄存器对应两个不同的物理寄存器。
eg. 当使用快速中断模式下的寄存器时,寄存器R8和R9分别记为 R8_fiq、R9_fiq;当使用用户模式下的寄存器时,寄存器R8和R9分别记为R8_usr、R9_usr。在这两种情况下使用的是不用的物理寄存器, - 系统没有将这几个寄存器用于任何特殊用途,但是当中断处理非常简单,仅仅使用R8~R14,FIQ处理程序可以不必执行保存和恢复中断现场的指令,从而可以使中断处理过程非常迅速。
- 每个寄存器对应两个不同的物理寄存器。
- R13~R14
对于R13、R14 来说,每个寄存器对应6个不同的物理寄存器,其中,用户模式和系统模式共用一个物理寄存器,另外5个对应其他的处理器模式。
R13_<mode> //mode: usr、svc、abt、und、irq、fiq
- R13(Stack Pointer)
- 在ARM中常用作栈指针(Stack Register,SR)。
- 在ARM指令集中,这只是一种习惯用法,并没有任何指令强制性地使用R13作为栈指针,用户也可以使用其他的寄存器作为栈指针
在Thumb指令集中,有一些指令强制性的使用R13作为栈指针。 - 每种异常模式拥有自己的物理的R13。应用程序初始化 R13,使其指向该异常模式专用的栈地址。
当进入异常模式时,可以将需要使用的寄存器保存在R13所指的栈中;当退出处理程序时,将保存在R13所指的寄存器值弹出。
这样就使异常处理程序不会破坏被其中断程序的运行现场。
- R14:连接寄存器(Link Register,LR)在ARM体系中具有下面两种特殊的作用:
- (1)每种处理器模式自己的物理R14中存放着当前子程序的返回地址。当通过 BL 或 BLX 指令调用子程序时,R14被设置为该子程序的返回地址。在子程序中,当把R14的值复制到程序计数器PC中时,子程序返回。可以通过下面两种方式实现子程序的返回
/* (1)执行下面任何一条命令 */
MOV PC , LR
BX LR
/* (2)在子程序入口使用下面的指令将PC保存到栈中 */
STMFD SP ! , { <register>, LR }
LDMFD SP ! , { <register>,PC }
- (2)当异常中断发生时,该异常模式特定的物理R14被设置成**该异常模式将要返回的地址**。对于有些异常模式,R14的值可能与将返回的地址有一个常数的偏移量。具体的返回方式与上面的子程序返回方式基本相同。
程序计数器 R15 PC(Program Counter)
- 由于ARM采用流水线机制,读取到的PC=当前指令地址+8个字节,即,PC指向当前指令的下两条指令的地址。
- 由于ARM指令是字对齐,PC值的第0位和第1位总为0;(因为是字对齐也就是4字节对齐方式,,也就是你的地址必须是4的倍数,显然PC的第0位和第一位是0,如果是半字对齐的话,那么就变成第0位必须为0)
- 当使用STR/STM指令来保存R15时,保存的可能是当前指令地址值加8字节或者12字节,取决于芯片的具体设计方式,因此尽量避免使用STR/STM保存R15的值
- 当成功向R15写入一个地址数值时,程序将跳转到改地址执行。由于ARM指令是字对齐,写入R15的地址值应该满足 bits [1:0]=0b00。
- 对于ARMv3以及更低版本,R15的地址值将与0xFFFF FFFC相与。
- 对于ARMv4以及更高版本,程序必须保证bits [1:0]=0b00;
- 对于Thumb指令,是半字对齐,R15的地址值将与0xFFFF FFFE相与。
1.5.2 程序状态寄存器 CPSR | SPSR
- CPSR(当前程序状态寄存器)可以在任何处理器模式下被访问,它包含条件标致位、中断禁止位、当前处理器模式标志以及其他的控制和状态位。
- 每一种异常处理器模式下都有一个专用的物理状态寄存器,称为SPSR(备份程序状态寄存器)。当特定的异常中断发生时,这个寄存器用于存放当前程序状态寄存器的内容。在异常中断退出时,可以用SPSR中保存的值来恢复CPSR。
- 由于用户模式和系统模式不是异常中断模式,所以他们没有SPSR。
- CPSR | SPSR 格式
31 | 30 | 29 | 28 | 27 | 26:8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
N | Z | C | V | Q | DNM(RAZ) | I | F | T | M4 | M3 | M2 | M1 | M0 |
1.条件标志位 N、Z、C、V
- N(Negative)
- 设置成当前指令运算结果的bit[31]的值
- 当两位补码表示的有符号整数运算,N=1表示运算结果为负数,N=0表示运算结果为正数
- Z(Zero)
- Z=1 表示运算结果为0;Z=0 表示运算结果不为0;
- 对于CMP指令,Z=1表示进行比较的两个数大小相等
- C(Carry)
- 在加法指令中(包括比较指令CMN),发生进位,则C=1,表示无符号数运算发生溢出;其他情况下C=0;
- 在减法指令中(包括比较指令CMP),发生借位,则C=0,表示无符号数运算发生溢出;其他情况C=1;
- 对于包含移位操作的非加/减法运算指令,C中包含最后一次被溢出的位的数值。
- 对于其他非加/减法指令,C位的值通常不受影响
- V(oVerflow)
- 对于加/减法运算指令,当操作数和运算结果为二进制的补码表示的带符号数时,V=1表示符号位溢出
- 通常其他指令不影响V位。
以下指令会影响CPSR中的条件标志位
- 比较指令,如CMP,CMM,TEQ和TST等
- 当一些算术指令和逻辑指令的目标寄存器不是R15时,这些指令会影响CPSR中的条件标志位。
- MSR可以向CPSR/SPSR中写入新值。
- MRC指令将R15作为目标寄存器时,可以把协处理器产生的条件标志位的值送到ARM处理器。
- 一些LDM指令的变种指令可以将SPSR的值复制到CPSR中,这种指令主要用于异常中断程序中返回。
- 一些带“位设置”的算术和逻辑指令的变种指令,也可以将SPSR的值复制到CPSR中,这种指令主要用于异常中断程序中返回。
2.Q标志位
bit[27] – > 主要用于增强的DSP指令是否发生溢出
3.CPSR中的控制位
低八位【I 、F、T、M[4:0] 】统称为控制位。
- 中断禁止位
- I = 1 时,禁止IRQ中断;
- F = 1时,禁止FIQ中断;
- T控制位
控制指令执行的状态,说明是ARM指令、还是Thumb指令。- ARMv4以及更高版本的T系列ARM处理器,
- T = 0执行ARM指令
- T = 1执行Thumb指令
- ARMv5以及更高版本的非T系列ARM处理器,
- T = 0执行ARM指令
- T = 1 表示强制下一条执行的指令产生未定义中断
- M控制位
M[4:0]控制处理器模式
- ARMv4以及更高版本的T系列ARM处理器,
4.CPSR中的其他位
CPSR中的其他位用于将来ARM版本的扩展。
1.6ARM体系的异常中断
3种方式控制程序的执行流程:
-
- 在正常程序执行过程中,每执行1条ARM指令,PC+4byte;每执行一条Thumb指令PC+2byte。整个过程按顺序执行
-
- 通过跳转指令,程序可以跳转到特定的地址标号处执行,或者到特定的子程序处执行。
- B 用于执行跳转操作
- BL 在执行跳转的同时保存子程序的返回地址
- BX 在执行跳转操作的同时,根据目标地址的最低位可与将程序状态切换到Thumb状态。
- BLX执行3个操作,跳到目标地址处执行,保存子程序的返回地址,根据目标地址的最低位可以将程序状态切换到Thumb。
- 当异常中断发生时,系统执行完当前指令后,跳转到相应的异常中断处理程序处执行。在异常中断处理程序执行完后,程序返回到发生中断的指令的下一条指令处执行。在进入异常中断处理程序时,要保护被中断的程序执行现场,在从异常中断处理程序退出时,要恢复被中断的程序的执行现场。
1.6.1 ARM中异常中断的种类
异常中断名称 | 含义 |
---|---|
复位(Reset) | 当处理器的复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行。复位异常中断一般有以下几种情况。 系统加电时;系统复位时;软复位:跳转到复位中断向量处执行; |
未定义的指令(Undefined Instruction) | 当ARM处理器或者是系统中的协处理器认为当前指令未定义时,产生未定义的指令异常中断。可以通过该异常中断机制仿真浮点向量运算 |
软件中断(Sofeware Interrupt,SWI) | 可用于用户模式下的程序调用特权操作指令。在实时操作系统(RTOS)中可以通过该机制实现系统功能调用 |
指令预取址中断(Prefetch Abort) | 如果处理器预取的指令不存在,或者该地址不允许当前指令访问,当该被预取的指令执行时,处理器产生指令预取中止异常中断 |
数据访问中止(Data Abort) | 如果数据访问指令的目标地址不存在,或者该地址不允许当前指令访问,处理器产生数据访问中止异常 |
外部中断请求(IRQ) | 当处理器的外部中断请求引脚有效,而且CPSR的I控制位被清除时,处理器产生IRQ异常中断,系统中个外设通常通过该异常中断请求处理器服务 |
快速中断请求(FIQ) | 当处理器的外部快速中断请求引脚 |
1.6.2 ARM处理器对异常中断的响应过程
(1)保存处理器当前状态、中断屏蔽位、以及各条件标志位。这是通过将CPSR的内容保存到将要执行的异常中断对应的SPSR
(2)设置CPSR中的对应位,使处理器进去响应的执行模式;禁止IRQ中断;进入FIQ模式时,禁止FIQ中断
(3)将寄存器lr_mode设置成返回地址
(4)将PC设置为该异常中断的中断向量地址,从而跳转到相应的异常中断处理程序处执行
1.6.3从异常中断处理程序中返回
(1)恢复被中断的程序的处理器状态,即将SPSR_mode寄存器内容复制到CPSR中。
(2)返回到发生异常中断的指令的下一条指令处执行,即把lr_mode寄存器的内容复制到PC中。
当异常中断发生时,PC所指的位置对于各种不同的异常中断时不同的,同样,返回地址也不同。
1.7ARM体系中的存储系统
1.7.1 ARM系统中的存储空间
使用单一的地址空间,该地址空间的大小为232**个**8位字节**。这些字节单元的地址都是无符号的32位数值。也可以看做是**230个32位的字单元,这些字节单元的地址可以被4整除,地址为A的字数据包括地址为A、A+1、A+2、A+3四个字节单元的内容。在ARMv4及以上版本,也可以看做2^31个16位的半字单元,这些半字单元的地址可以被2整除,地址为A的半字数据包包括A、A+1两个字节单元的内容。
1.7.2 ARM存储器格式
Big-endian
Little-endian
1.7.3非对齐的存储访问操作
1.非对齐的指令预取操作
如果写到寄存器PC中的值非字对齐
- ARM状态下
- 指令执行的结果不可预知
- 地址中的最低两位被忽略
- Thumb
- 指令执行的结果不可预知
- 地址中的最低位被忽略
如果系统中指定,当发生非对齐的指令时,忽略地址中的相应位,则由存储系统实现这种“忽略”,也就是说,这时该地址原封不动的送到存储系统。
2.非对齐的数据访问操作
对于Load/Store操作,如果是非对齐的数据访问操作,则系统定义了一下三种结果
- 执行的结果不可预知
- 忽略字单元地址的低两位的值,即访问地址为(addr & 0xffff fffc)的字单元;
- 忽略半字单元地址的最低位的值,即访问地址为(addr & 0xffff fffe)的字单元;
当发生非对齐的数据访问时,到底采用哪一种,是由个指令指定的。
1.7.2 指令预取和自修改代码
在CPU执行当前指令的同时,可以从存储器中预取其后若干条指令,具体预取多少条,不同的ARM实现中有不同的数值。
预取的指令并不一定得到执行:
- 当前指令完成后,如果发生了异常中断,程序将会跳转到异常中断处理程序处执行,当前预取的指令将被抛弃。
- 执行了跳转指令,当前预取的指令也会被抛弃。
自修改代码指的是代码在执行过程中可能修改自身。
当指令被预取后,在该指令被执行前,如果有数据访问指令修改了位于主存中的该指令,这是被预取的指令和主存中的指令不同,从而可能使执行的结果发生错误。