ARM基础知识和特点

处理器内核系列

  • T:支持16位的Thumb指令集
  • D:支持JTAG片上调试
  • M:支持用于长乘法操作(64位结果)的ARM指令,包含快速乘法器
  • I:带有嵌入式追踪宏单元 ETM用来设置断点和观察点的调试硬件

    三级流水

    ARM7采用冯诺伊曼结构,与之对应采用了三级流水,分别为取指,译码,执行。
    三级流水阻断的原因:执行单元的工作往往占用多个时钟周期,存在存储器访问指令,跳转指令的情况下会出现流水线阻断的情况,导致流水线性能下降。

    五级流水

    ARM9采用哈佛架构,避免了数据访问和取指的总线冲突。
    五级流水如下:

  • 取指:从缓存中读取指令

  • 译码:对指令进行译码
  • 执行:进行运算和位移操作。如果是对存储器操作的指令,则在ALU中计算出要访问的存储器地址。
  • 存储器访问:用来实现数据缓冲功能
  • 存储器回写:将指令运算或操作结果写回目标寄存器中。

    大小核

    Cortex-A53,Cortex-A57这两款处理器可以整合为大小核心伴侣处理器架构,以满足高性能与低功耗的需求。这两个处理器是独立运作的。

    A15与A7的关系

    A7与A15体系结构和功能集完全相同,不同之处在于A7侧重于提供最佳能效。

    运行(工作)模式

    ARM微处理器支持7种运行模式。
  1. 用户模式
  2. 系统模式
  3. 快速中断模式
  4. 外部中断模式
  5. 管理模式
  6. 数据访问终止模式
  7. 未定义指令终止模式

    特权模式

    除了用户模式之外,其他模式均为特权模式。
    特权模式可以自由的切换处理器模式,而用户模式不能直接切换到别的模式。

    异常模式

    除了用户模式和系统模式外,其他五种模式被称为异常模式。
    除了可以通过程序切换进入外,也可以由特定的异常进入。
    每种异常模式都有一些独立的寄存器。

    工作状态

    有两种工作状态:ARM状态和Thumb状态。

    ARM状态

    处理器执行32位的ARM指令,ARM指令要求字对齐。

    Thumb状态

    处理器执行16位的Thumb指令,要求半字对齐。

    工作状态的切换

    ARM在开始执行代码时总是处于ARM状态。也即复位后进入ARM状态。
    使用带状态切换的跳转指令。比如使用BX指令,当操作数寄存器最低位[0]为1时,可使微处理器从ARM状态切换到Thumb状态。
    处理器工作在Thumb状态,如果发生异常并进入异常处理子程序,则异常处理完毕返回时,自动从ARM状态切换到Thumb状态。

使用带状态切换的跳转指令。比如使用BX指令,当操作数寄存器最低位[0]为0时,可使微处理器从Thumb状态切换到ARM状态。
处理器工作在Thumb状态,如果发生异常并进入异常处理子程序,则进入时处理器自动从Thumb状态切换到ARM状态。

寄存器

寄存器包括R0~R15。

  • 未分组寄存器(R0~R7)
  • 分组寄存器(R8~R14)
  • 程序计数器R15

    未分组寄存器

    R0到R7。
    对于任何处理器模式,这些寄存器都对应于相同的32位物理寄存器。

    分组寄存器

    R8到R14。
    他们所对应的物理寄存器取决于当前的处理器模式。
    其中R8到R12有两个分组的寄存器。一个用于FIQ模式,另一个用于FIQ之外的模式。这样在发生FIQ中断后可以加速FIQ的处理速度。
    R13和R14分别有6个分组的物理寄存器。一个用于用户和系统模式,其余5个用于5种异常模式。
模式 寄存器后缀
管理 _svc
终止 _abt
未定义 _und
中断 _irq
快中断 _fiq

用作特殊作用的寄存器

  • R13常作为堆栈指针(SP)。
  • R14为链接寄存器(LR)。模式自身的R14版本用于保存子程序返回地址。当发生异常时,将R14对应的异常模式版本设置为异常返回地址。
  • R15为程序计数器(PC)。它指向正在取指的地址。在ARM状态下,位[1:0]为0,位[31:2]用于保存PC;在Thumb状态下,位[0]为0,位[31:1]用于保存PC。

    状态寄存器

    CPSR为程序状态寄存器。另一个寄存器SPSR可以作为CPSR的备份。与CPSR不同的是SPSR对于每个异常状态均有一个寄存器。
    image.png

  • N位(CPSR[31]):做运算时,N=1表示结果为负,N=0表示结果为正数或零。

  • Z位(CPSR[30]):Z=1表示运算结果为零。Z=0表示运算结果非零。
  • C位(CPSR[29]):溢出或借位位:
    • 加法运算:当运算结果产生了进位时(无符号数溢出),C=1,否则C=0。
    • 减法运算:当运算结果产生了借位(无符号数溢出),C=0,否则C=1.
    • 对于包含移位操作的非加/减运算指令,C为移出值的最后一位。
    • 对于其他的非家/减指令,C的值通常不变。
  • V位(CPSR[28]):对于有符号加减法,V=1表示符号位溢出。

    控制位

  • I位(CPSR[7]):I=1禁止IRQ中断。

  • F位(CPSR[6]):F=1禁止FIQ中断。
  • T位(CPSR[5]):T=1表示程序运行于Thumb状态。
  • M0~M4位(CPSR[4:0]):寄存器的值表示程序运行在何种运行模式下。

    异常状态

    异常的处理过程

  1. 将CPSR复制到SPSR中
  2. 对CPSR进行设置
    1. 根据异常类型,强制设置CPSR的工作模式位
    2. 设置中断禁止位,以禁止中断发生
    3. 如果处理器处于Thumb状态,则切换到ARM状态
  3. 将下一条指令的地址存入要跳转的中断的状态模式相应的链接寄存器LR
  4. 强制PC从相关的异常向量地址取下一条指令执行
    1. SPSR_<Exception_Mode>=CPSR
    2. CPSR[4:0]=Exception Mode Number
    3. CPSR[5]=0 ;切换到ARM工作状态
    4. if<Exception_Mode>==Reset or FIQ then
    5. CPSR[6]=1 ;如果中断为复位或是FIQ,则禁止FIQ中断
    6. CPSR[7]=1 ;禁止IRQ中断
    7. R14_<Exception_Mode>=Return Link
    8. PC=Exception Vector Address
    具体的各种异常的伪码表示参见PPT

    异常向量

    image.png
    可以看出比较特殊的是复位和软件中断均进入管理模式。

    异常优先级

    | 优先级 | 异常 | | —- | —- | | 1(最高) | 复位 | | 2 | 数据中止 | | 3 | FIQ | | 4 | IRQ | | 5 | 预取指令中止 | | 6(最低) | 未定义指令,SWI |

从异常返回

异常处理完毕后会执行一下几步操作从异常返回

  1. 将SPSR复制回CPSR中
  2. 将LR的值减去相应偏移量后送到PC中

复位异常处理程序不需要返回

ARM处理器的数据类型

ARM的字长为32位。
ARM微处理器需要自然对界。
字需要4字节对齐。地址开头的低两位为0。
半字需要2字节对齐。地址的最低位为0。
字节则是任意地址对齐。
ARM所支持的最大寻址空间是2^32字节。

字对齐,半字对齐

如果一个数据是从偶地址开始的连续存储,那么他是半字对齐。
如果一个数据是以能被4整除的地址开始的连续存储,那么他就是字对齐。

大端模式,小端模式

大端模式就是地址的低位存储数值的高位。
小端模式就是地址的低位存储数值的低位。

ARM指令系统

指令条件码表

条件助记符 标志位 含义
EQ Z=1 相等
NE Z=0 不相等
HI C=1,Z=0 无符号数大于
LS C=0,Z=1 无符号数小于或等于
LT 有符号数小于
GT 有符号数小于或等于

寻址方式

立即寻址

  1. ADD R3,R0,#1 ;R3=R0+1

立即数的表示以#为前缀

寄存器寻址

  1. ADD R0,R1,R2 ;R0=R1+R2

将寄存器内部的值直接相加

寄存器间接寻址

  1. LDR R0,[R1];R0<-[R1]
  2. SDR R0,[R1];R0->[R1]

寄存器内的值作为操作数的地址,而操作数本身存放在存储器中。

基址变址寻址

  1. ;前索引寻址举例
  2. LDR R0,[R1,#4] ;R0<-[R1+4]
  3. ;后索引寻址举例
  4. LDR R0,[R1],#4 ;R0<-[R1];R1<-R1+4
  5. ;带自动索引的前索引寻址举例
  6. LDR R0,[R1,#4]! ;R0<-[R1+4];R1<-R1+4
  7. ;基址加索引寻址举例
  8. LDR R0,[R1,R2] ;R0<-[R1+R2]

多寄存器寻址

  1. LDM/STM+IA/IB/DA/DB
  2. ;举例
  3. LDMIA R0!,{R1,R2,R3,R4} ;R1<-[R0]
  4. ;R2<-[R0+4]
  5. ;R3<-[R0+8]
  6. ;R4<-[R0+12]

多寄存器指令的后缀含义如下:

  • I:Increament 指针每次增加4
  • D:Decrement 指针每次减少4
  • A:After 在寻址访存之后改变指针的值
  • B:Before 在寻址访存之前改变指针的值

image.png

寄存器位移寻址

LSL(较重要):逻辑左移。不会改变状态寄存器的值。
LSR:逻辑右移。同上。
ASR:算术右移。操作数符号不变。

  1. LDR R0,[R1,R2,LSL#2]! ;R0<-[R1+R2*2];R1<-R1+R2*2;

相对寻址

  1. BL LOOP ;跳转到LOOP处并将下一条指令的地址赋值给LR寄存器
  2. ...
  3. LOOP
  4. ...
  5. MOV PC,LR ;从子程序中返回,将指令的地址重新赋值。

堆栈寻址

堆栈有两种区别。
堆栈指针指向的地址是最后一个压入堆栈的数据时,称为满堆栈。指向下一个将要放入数据的空位置时,称为空堆栈。
当堆栈从低地址向高地址生成时,称为递增堆栈,当堆栈由高地址向低地址生成时,称为递减堆栈。

  • FA:满递增堆栈
  • FD:满递减堆栈
  • EA:空递增堆栈
  • ED:空递减堆栈

    加载/存储指令

    1. LDR R0,[R1]
    2. LDR R0,[R1,R2]
    3. LDR R0,[R1.#8]
    4. LDR R0,[R1,R2,LSL#2]!
    5. LDR R0,[R1],R2,LSL#2
    LDRB 只读取前8位
    LDRH只读取前16位(半位)
    STL指令

    数据处理指令

    MOV,MVN,CMP,TST,TEQ,ADD,ADC,SUB,SBC,AND,ORR,EOR,BIC,MUL,MLA,SMULL,SMULAL

    状态寄存器访问指令

    MRS,MSR