Linux嵌入式系统开发
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.5 ARM编程模型

ARM编程模型主要包括数据类型、存储器格式、处理器工作状态、处理器运行模式、寄存器组织和内部寄存器6个方面。

3.5.1 数据类型

(1)数据分类

数据类型有3种:

1)字节(8位)。

2)半字(16位)。

3)字(32位)。

(2)符号数

1)无符号数:N位数据使用正常的二进制格式表示,范围为0~2N-1的非负整数。

2)有符号数:N位数据使用补码表示,其范围为-2N-1~2N-1-1的整数。

(3)字对齐

1)字需要4字节对齐,地址的低2位为00。

2)半字需要2字节对齐,地址的最低2位为0。

结构如图3-5所示。

图3-5 数据类型的结构

3.5.2 存储器格式

ARM体系结构将存储器看作是从“0”地址开始的字节的线性组合。

从0字节到第3个字节放置第1个存储的字数据,从第4个字节到第7个字节放置第2个存储的字数据,依次排列。

作为32位的微处理器,ARM体系结构所支持的最大寻址空间为4GB。

ARM体系结构可以用两种方法存储字数据,称为大端格式和小端格式,具体说明如下:

(1)大端格式

字数据的高字节存储在低地址中,而字数据的低字节则存储在高地址中。

大端格式存储字数据如图3-6所示。

(2)小端格式

与大端存储格式相反,在小端存储格式中,低地址中存储的是字数据的低字节,高地址中存储的是字数据的高字节。

小端格式存储字数据如图3-7所示。

图3-6 大端格式存储字数据

图3-7 小端格式存储字数据

3.5.3 处理器工作状态

ARM处理器可以在两种工作状态之间切换。ARM和Thumb之间状态的切换不影响处理器的模式或寄存器的内容。

1)进入Thumb状态。当操作数寄存器的状态位[0]为“1”时,执行BX指令进入Thumb状态。如果处理器在Thumb状态进入异常,则当异常处理返回时,自动转换到Thumb状态。

2)进入ARM状态。当操作数寄存器的状态位[0]为“0”时,执行BX指令进入ARM状态,处理器进行异常处理。在此情况下,把PC放入异常模式链接寄存器中。从异常矢量地址开始执行也可以进入ARM状态。

通过BX指令在ARM状态和Thumb状态之间切换。

;从ARM状态切换到Thumb状态
LDR R0,=Lable+1
BX R0
;从Thumb状态切换到ARM状态
LDR R0,=Lable
BX R0

其中,Lable为跳转地址标号;地址最低位为“1”,表示切换到Thumb状态;地址最低位为“0”,表示切换到ARM状态。

3.5.4 处理器运行模式

ARM微处理器支持的7种运行模式如下:

1)usr(用户模式):ARM处理器正常程序执行模式。

2)fiq(快速中断模式):用于高速数据传输或通道处理。

3)irq(外部中断模式):用于通用的中断处理。

4)svc(管理模式):操作系统使用的保护模式。

5)abt (数据访问终止模式):当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护。

6)sys(系统模式):运行具有特权的操作系统任务。

7)und(未定义指令中止模式):当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真。

ARM微处理器的运行模式可以通过软件改变,也可以通过外部中断或异常处理改变。

大多数的应用程序运行在用户模式下,当处理器运行在用户模式下时,某些被保护的系统资源是不能被访问的。

除用户模式外,其余的6种模式称为非用户模式,或特权模式;其中除去用户模式和系统模式外的5种又称异常模式,常用于处理中断或异常,以及需要访问受保护的系统资源等情况。

ARM处理器在每一种处理器模式下均有一组相应的寄存器与之对应。即在任意一种处理器模式下,可访问的寄存器包括15个通用寄存器(R0~R14)、1~2个状态寄存器和程序计数器。在所有的寄存器中,有些是在7种处理器模式下共用的同一个物理寄存器,而有些寄存器则是在不同的处理器模式下有不同的物理寄存器。

3.5.5 寄存器组织

ARM处理器的37个寄存器被安排成部分重叠的组,不是在任何模式都可以使用,寄存器的使用与处理器状态和工作模式有关。如图3-8所示,每种处理器模式使用不同的寄存器组。其中,15个通用寄存器(R0~R14),1个或2个状态寄存器和程序计数器是通用的。

(1)通用寄存器

通用寄存器(R0~R15)可分成不分组寄存器R0~R7、分组寄存器R8~R14和程序计数器R15。

1)不分组寄存器R0~R7

不分组寄存器R0~R7是真正的通用寄存器,可以工作在所有的处理器模式下,没有隐含的特殊用途。

图3-8 寄存器组织

2)分组寄存器R8~R14

分组寄存器R8~R14取决于当前的处理器模式,每种模式有专用的分组寄存器用于快速异常处理。

寄存器R8~Rl2可分为两组物理寄存器。一组用于FIQ模式;另一组用于除FIQ外的其他模式。第一组访问R8_fiq~R12_fiq,允许快速中断处理;第二组访问R8_usr~R12_usr,寄存器R8~R12没有任何指定的特殊用途。

寄存器R13~R14可分为6个分组的物理寄存器。1个用于用户模式和系统模式,而其他5个分别用于svc、abt、und、irq和fiq 5种异常模式。访问时需要指定它们的模式,如,R13_<mode>,R14_<mode>;其中,<mode>可以从usr、svc、abt、und、irq和fiq 6种模式中选取1个。

在其他情况下,将R14当作通用寄存器。类似地,当中断或异常出现,或当中断或异常程序执行BL指令时,相应的分组寄存器R14_svc、R14_irq、R14_fiq、R14_abt和R14_und用来保存R15的返回值。

3)程序计数器R15

在ARM状态,位[1:0]为“0”,位[31:2]保存PC。

在Thumb状态,位[0]为“0”,位[31:1]保存PC。

(2)程序状态寄存器

寄存器R16用于程序状态寄存器CPSR,在所有处理器模式下都可以访问CPSR。CPSR包含条件码标志、中断禁止位、当前处理器模式及其他状态和控制信息。每种异常模式都有一个程序状态保存寄存器SPSR,当异常出现时,SPSR用于保存CPSR的状态。

CPSR和SPSR的格式如下:

1)条件码标志

N、Z、C、V(Negative、Zero、Carry、oVerflow)均为条件码标识位。CPSR中的条件码标志可由大多数指令检测以决定指令是否执行。在ARM状态下,绝大多数指令都是有条件执行的。条件码标志的通常含义如下:

■ N:假如是带符号二进制补码,那么,若结果为负数,则N=1;若结果为正数或零,则N=0。

■ Z:若指令的结果为“0”,则置“1”,否则置“0”。

■ C:可用如下4种方法之一设置:

加法:若加法产生进位,则C置“1”,否则置“0”。

减法:若减法产生借位,则C置“0”,否则置“1”。

对于结合移位操作的非加法/减法指令,C置为移出值的最后1位。

对于其他非加法/减法指令,C通常不改变。

■ V:可用如下两种方法设置,即

对于加法或减法指令,当发生带符号溢出时,V置“1”,认为操作数和结果是补码形式的带符号整数。

对于非加法/减法指令,V通常不改变。

2)控制位

程序状态寄存器PSR的最低8位I、F、T和M[4:0]用作控制位,当异常出现时改变控制位。处理器在特权模式下时,也可由软件改变。

■ 中断禁止位

I:置“1”,则禁止IRQ中断;

F:置“1”,则禁止FIQ中断。

■ T位

T=0:指示ARM执行;

T=1:指示Thumb执行。

■ 模式控制位

M4、M3、M2、Ml和M0(M[4:0])是模式位,决定处理器的工作模式,参见表3-2。

表3-2 M[4:0]模式控制位

(3)Thumb状态的寄存器集

Thumb状态下的寄存器集是ARM状态下的寄存器集的子集。程序员可以直接访问8个通用寄存器(R0~R7)、PC、SP、LR和CPSR。每一种特权模式都有一组SP、LR和SPSR。

■ Thumb状态R0~R7与ARM状态R0~R7是一致的。

■ Thumb状态CPSR和SPSR与ARM的状态CPSR和SPSR是一致的。

■ Thumb状态SP映射到ARM状态R13。

■ Thumb状态LR映射到ARM状态R14。

■ Thumb状态PC映射到ARM状态PC。

Thumb状态寄存器与ARM状态寄存器的关系如图3-9所示。

图3-9 Thumb状态寄存器映射到ARM状态寄存器

3.5.6 内部寄存器

内部寄存器主要分为R14寄存器和R15寄存器两种类型,下面分别对这两种寄存器的功能进行介绍。

(1)R14寄存器

R14寄存器调用步骤如下:

1)程序A执行过程中调用程序B。

2)程序跳转至标号Lable,执行程序B。同时硬件将BL Lable指令的下一条指令所在地址存入R14。

3)程序B执行后,将R14寄存器的内容放入PC,返回程序A。

R14寄存器调用如图3-10所示。

图3-10 R14寄存器调用

(2)R15寄存器

1)读R15的限制

正常操作时,从R15读取的值是处理器正在取址的地址,即当前正在执行指令的地址加上8字节。由于ARM指令总是以字为单位,所以,R15寄存器的最低两位总是为零。

当使用STR或STM指令保存R15时,这些指令可能将当前指令地址加8字节或加12字节保存。偏移量是8还是12取决于具体的ARM芯片,但是对于一个确定的芯片,这个值是一个常量。所以,最好避免使用STR和STM指令来保存R15,如果很难做到,那么应在程序中计算出该芯片的偏移量。

2)写R15的限制

正常操作时,写入R15的值被当作一个指令地址,程序从这个地址处继续执行。

由于ARM指令以字节为边界,因此,写入R15的值最低两位通常为“0b00”。具体的规则取决于内核结构的版本。

在ARM结构V3版及以下版本中,写入R15的值的最低两位被忽略,因此,跳转地址由指令的实际目标地址和0xFFFFFFFC相与得到。

在ARM结构V4版及以上版本中,写入R15的值的最低两位为“0”,如果不是,结果将不可预测。