ARM通用寄存器及状态寄存器详解

描述

笔者来聊聊ARM通用寄存器以及状态寄存器的认识与理解。

ARM通用寄存器

对于处理器来说,寄存器可以作为暂存器,存储临时结果,也可以作为输入数据,方便运算,也可以作为一种索引,去访问存储器,其作用各种各样。

CortexM3/M4

CortexM3/M4是比较常用的ARM架构,很多厂商都采用了这样的架构,比如ST公司的stm32,广受大家欢迎,还有NXP的MK60芯片,一直在飞思卡尔比赛中很受欢迎,还有国产兆易创新的GD32,亚特力的AT32,国民技术的N32系列。

其在嵌入式领域非常受欢迎,相对方便上手,功能齐全,满足一般的对MCU的需求。

其寄存器模型如下:状态寄存器

通用目的寄存器R0-R7

,低组寄存器,32bit,16位thumb以及32位的thumb-2指令均可以访问

可以看到R0、R1、R2三个作为参数传递进入。

后面R0作为结果传出进行比较。

传入参数是数组,为什么不直接传地址(LDR),而是通过DCD指令来传递呢?

这是因为LDR取地址的范围有限,LDR Rn,#立即数地址,该地址只是是小范围(4KB?),所以可以看到DCD的地址就在不远处(6A92 - 6D48相差不远),而存储器的地址则在2000000范围,与其地址相差较大,从图二来看 DCD后的地址,其实是通过DCD的地址先寻址,寻址后再作为地址,继续寻址。
状态寄存器
状态寄存器

R0-R3一般作为参数传递,如果参数再多,则通过压栈的方式传递

R0、R1还会作为返回值进行传递,如果是32位则是R0,64位则会用R0-R1状态寄存器

通用目的寄存器R8-R12

,高组寄存器,32bit,较少的16位thumb指令可以访问,一般是 thumb-2指令访问。

R11一般用作FP指针,保存栈帧(在加上编译选项时 ,见上篇文章,下文SP、LR同理ARM开发中几个常见的寄存器详解。

栈指针R13(SP) 指示当前栈所指位置。

链接寄存器R14(LR) 保存程序返回地址。

程序计数器R15(PC)

程序运行的当前位置。

下图一PC作为基址地址,然后去访问存储器,0x4079a1c+480 =0x4079c04

下图二直接将0x4079c04 作为地址给r0状态寄存器状态寄存器

指令对齐半字或者字地址,最低位为0

特殊跳转指令,需要将PC 最低位表示Thumb状态,否则会触发异常。

PC有时候会作为基址寄存器,然后加地址偏移去访问数据

CortexR5

Cortex R系列继承了ARM7架构下的系统模型,有多组工作模式,每个模式都有自己的地址空间(堆栈地址SP)状态寄存器

CortexR5 属于ARMv7指令集。

与CortexM3/4一致,其R0-R7 以及R8-R12的作用

user模式和sys模式共用一套寄存器,即共享

user/sys、FIQ、SVC、ABT、IRQ以及UND模式 下,LR、SP、SPSR均是独立,切换CPSR 模式之后,SP、LR及SPSR自动切换成相应模式下的寄存器值

FIQ 之所以被称之快速中断,是因为有独立的R8-R12寄存器,不需要压栈 ,直接使用,

SPSR是保存上一个模式的CPSR。

ARMv7的一般AR系列的寄存器模型和上述的基本相同,有一些新的扩展,

状态寄存器

增加了Hyp模式以及Mon模式,分别用于虚拟扩展以及安全扩展,

Hyp模式下的LR为ELR,记录异常时的返回地址,其他均一致。

CortexA53

状态寄存器

r0-r7 用来做参数传递或者发返回结果。

r8 间接的结果位置寄存器

r9-r15 暂存器 保存临时结果

r16-r17 动态链接(系统并不是所有地址都可以跳转)(链接器内部插入代码)所需要的寄存器

r18 the Platform ABI专用的寄存器 来保存内部程序状态(为了平台通用性 避免使用)

r19-r28 被调用者保存的寄存器(相对来说还有调用者保存寄存器 在CortexM3/4就有很好体现)

r29 FP寄存器,需要加编译选项

r30 链接寄存器

SP 栈指针,

PC 程序寄存器,状态寄存器可以看到程序调用时,函数类型为9个参数,汇编代码x0-x7作为参数传递进去,最后一个参数,压栈进行传递,str x9,[SP] 。还用到了 blr 通过寄存器去进行链接跳转 最后通过b 跳转返回。

状态寄存器

寄存器通常是CPSR(Current Program state register),用来表示当前程序运行的状态、模式、运算结果状态、中断状态等。,比如下面这个CPSR寄存器模型。状态寄存器

标志位域

说明解释:表示程序的运行结果的状态,可以用来跳转,例如:结果是否为0,结果是否有进位,结果是否溢出,结果是否为负数等等。状态寄存器

符号有NCVZ,分别是负数(Negative)、进位(Carry)、溢出(Overflow)、为0(Zero)标志。

衍生出许多跳转指令,近范围或者函数范围内跳转,比如以下这些指令

BEQ、BNE 通过判断Z==1,BEQ为相等则跳转,比如CMP X0,X1 BEQ

BCS、BCC通过判断C==1,BCS为大于等于则跳转,BCC为小于则跳转

BMI、MBL 通过判断N==1,BMI 为负数则跳转,BPL为整数则跳转

BVS、BVC 通过判断V==1,溢出则跳转,BVC为非溢出则跳转

BHI、BLS通过判断C == 1 and Z == 0 意思就是大于则跳转,

BGE、BLT 通过判断N == 1 and V == 1,或者 N == 0 and V == 0 有符号数大于等于

BGT、BLE 通过判断Z=0, N == 1 and V == 1 或者 Z=0 N == 0 and V == 0 有符号数大于状态寄存器

相关数字运算对标志位的影响。状态寄存器

异常中断控制域

比如常见的DAIF 中断屏蔽位,分别为:

处理器状态debug中断 屏蔽位:查看点、断点以及系统单步运行

系统错误中断屏蔽位(通常是异步的错误)

普通中断屏蔽位

快速中断屏蔽位状态寄存器常见的中断控制域如上图所示,

CortexM3/4 单独存在一个寄存器primask,可以屏蔽中断,只有普通中断,没有快速中断(支持嵌套,所以快速与否感觉关系不大,同时进入中断后,硬件自动压栈相关寄存器,也提高了中断速度),在cpsr中没有中断屏蔽相关,

CortexR5以及A53系列中均有这样的中断控制域,可以访问临界资源时屏蔽中断,

模式控制域

CPSR的低五位为模式控制位,控制当前CPU为何种模式,设置各种模式则是为了处理异常以及分层管理,低级无法访问特定资源,而特权模式则可以进行资源上的操作。状态寄存器

通过写CPSR的低五位,可以控制系统处于何种模式。

通过读CPSR的第五位 也可以知道当前处于何种模式,判断程序发生了什么故障。

mode description restriction
User Mode 运行用户程序,非特权模式 ,无法处理异常,除非异常,否则无法改变当前模式 对系统资源的访问进行限制(外设以及memory)
SVC Mode 用于系统管理,比如系统下的资源访问,以及OS的调度管理,可以通过软件触发,特权模式 ,执行SVC指令可以进入到本异常,复位之后进入该模式 ,(正常行为,软件触发到)  
system Mode 与用户模式共享所有寄存器,特权模式,不能通过异常进入,(正常行为,软件触发)  
Abort Mode Data Abort或者Prefetch Abort,前者是数据访问出错,后面是取指令错误,特权模式,(异常行为,硬件检测到)  
Undefined Mode 指令相关的异常处理,例如执行到未定义的指令,特权模式,(异常行为,硬件检测到)  
FIQ Mode 特权模式,处理快速中断,(正常行为,硬件触发到)  
IRQ Mode 特权模式,处理普通终端,(正常行为,硬件触发到)  

指令选择域

T Value 指令集 描述
0 ARM指令集 32位DWORD对齐的指令
1 Thumb指令集 部分为16位半字(half word)对齐的指令,增加代码密度,减少Image size
X 关联 两种指令集可以混合使用,通过状态来表征,比如通过bx 、blx可以切换指令集

大小端控制域

endian state value 模式 描述 设置指令
0 小端模式 memory 低字节在低位 SETEND LE
1 大端模式 memory 低字节在高位 SETEND BE

执行状态控制域

一些控制系统状态的标志位,比如ARMv8-A系列

标志属性 描述 HTML
SP_ELx Stack pointer register selected,' 比如SP_EL0 或者SP_EL3
EL "异常等级" “EL0、EL1、EL2以及EL3”
SS 软件单步控制 for debugger make PE single-step instruction

  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分