嵌入式 | ARM工作模式详解
ARM v4版本的处理器有以下两个工作状态:
- ARM状态:32位,执行字对准的ARM指令。(性能好,代码密度小
- Thumb状态:16位,执行半字对准的Thumb指令。(性能差,代码密度大)
进入Thumb状态的方法是:
- 执行BX指令,并设置操作数寄存器的状态(位[0])为1。
- 在Thumb状态进入异常(所有的异常都是ARM状态),当异常处理返回时自动转换Thumb指令。
进入ARM状态的方法是:
- 执行BX指令,并设置操作数寄存器的状态(位[0])为0。
- 进入异常时,将PC放入异常模式链接寄存器中,从异常向量地址开始执行也可进入ARM状态。
ARM处理器的7种工作模式:
处理器模式 | 说明 |
---|---|
用户模式(User) | 正常程序执行模式 |
异常模式(FIQ) | 快速中断处理,用于支持高速数据传送或通道处理 |
异常模式(IRQ) | 一般中断处理 |
异常模式(Supervisor) | 特权模式,用于系统初始化或操作系统的功能 |
异常模式(Abort) | 存储器保护异常处理 |
异常模式(Undefined) | 未定义指令异常处理 |
系统模式(System) | 运行操作系统任务(ARM v4以上版本) |
注意:除了User模式外,其他模式都称为特权模式,可以存取系统中的任何资源。User模式下程序不能访问有些受保护内容,也不能直接改变CPU的模式,只能通过异常的形式来处理改变CPU的当前运行状态。Abort和Undefined模式都是错误引起的。
ARM处理器有37个寄存器
31个通用寄存器:程序计数器、堆栈及其他通用寄存器
6个状态寄存器:(不能同时看到)
ARM工作状态寄存器:
<div align=center>
Thumb工作状态寄存器:
<div align=center>
ARM状态与Thumb状态寄存器关系,如下图:
<div align=center>
处理器模式与寄存器的关系:
异常发生时伴随的模式切换意味着, 被调用的异常处理程序会访问(影子寄存器):
它自己的堆栈指针 (SP_<mode>)
- 它自己的链接寄存器 (LR_<mode>)
- 它自己的备份程序状态寄存器 (SPSR_<mode>)
- 如果是FIQ异常处理, 5个其它的通用状态寄存器 (r8_FIQ to r12_FIQ)
- 其它寄存器和原来模式下的寄存器是相同的
通用寄存器是R0-R15的寄存器,分为三类
- 没有对应影子寄存器的寄存器R0-R7 (不同模式公用的)
- 有对应影子寄存器的寄存器R8-R14
- 程序计数器R15 (或者PC)
注意:影子寄存器是指该寄存器在不同的模式下对应的物理寄存器
通用寄存器特别说明:
R8-R12各有两组物理寄存器:一组为FIQ模式,另一组是除FIQ以外的其他模式。
R13-R14各有6个分组的物理寄存器,一个用于用户模式和系统模式,其他5个分别用于5种异常模式。
R13(SP指针)被用作栈指针,通常在系统初始化时需要对所有模式下的SP指针赋值,当CPU在不同的模式时栈指针会被自动切换成相应模式下的值。
R14(LR指针)有两个用途,一是在调用子程序时用于保存调用返回地址,二是在发生异常时用于保存异常返回地址。
特别注意:PC指向的是正被取指的指令,而不是正在执行的指令。(流水线影响)
CPSR(当前程序状态寄存器):
- 条件标志
- 中断使能标志
- 当前处理器的模式
- 其它的一些状态和控制标志
<div align=center>
寄存器编号 | 可选名字 | ATPCS寄存器用法 |
---|---|---|
R0~R3 | A1~A4 | 参数寄存器,在调用函数时,用来存放前4个函数参数和返回值,多出的存堆栈中。(易失的) |
R4~R8 | V1~V5 | 通用变量寄存器。(非易失性的) |
R9 | V6 sb | 通用变量寄存器。在与读/写位置无关的编译情况下,用作基址寄存器。(非易失性的) |
R10 | V7 sl | 通用变量寄存器。在使用堆栈边界检查的编译情况下,R10保存堆栈边界的地址。(非易失性的) |
R11 | V8 fp | 通用变量寄存器。在使用结构指针的情况下,必须保存这个寄存器中调用函数的变量值。(非易失性的) |
R12 | Ip | 通用临时过渡寄存器(易失的) |
R13 | sp | 堆栈指针,指向满递减堆栈 |
R14 | lr | 链接寄存器,在函数调用时用以保存返回地址 |
R15 | pc | 程序计数器 |
注意:带四个或更少的参数的函数,要比多于四个参数的效率到很多,多于四个,参数要存放在堆栈中,调用函数,须通过堆栈。
拓展:esp:x86的堆栈,ebp:x86的基地址。