ARMv7-A 那些事 - 3.程序状态寄存器

By: Ailson Jack
Date: 2023.09.16
个人博客:http://www.only2fire.com/
本文在我博客的地址是:http://www.only2fire.com/archives/155.html,排版更好,便于学习,也可以去我博客逛逛,兴许有你想要的内容呢。

微信公众号:嵌入式那些事

程序状态寄存器的作用就是反映处理器的状态信息。在程序运行期间我们可以通过查看程序状态寄存器的状态位来进行程序的分支跳转处理,或者我们可以设置程序状态寄存器的模式位来改变处理器的运行模式,或者我们可以设置程序状态寄存器的中断屏蔽位来屏蔽中断。

在任何时刻,我们可以访问处理器的16个寄存器(R0~R15)和当前程序状态寄存器(Current Program Status Register,CPSR)。用户模式下的程序访问的程序状态寄存器叫做APSR(Application Program Status Register),APSR是CPSR在用户模式下的别名,因为在用户模式下CPSR的部分域是不能操作的,因此CPSR的部分域被屏蔽后就是APSR。

CPSR寄存器组成

在所有模式下均可以访问到CPSR,只是在用户模式下CPSR的部分域是不能操作的,当前程序状态寄存器(CPSR)的位组成如下图所示:

在这里插入图片描述
各个位域的说明如下:

标志说明
31N当运算结果为负且运算指令要求更新寄存器时,该位会被置位。
30Z当运算结果为0且运算指令要求更新寄存器时,该位会被置位。
29C当运算结果产生进位且指令要求更新寄存器时,该位会被置位。
28V当运算结果产生符号位溢出且指令要求更新寄存器时,该位会被置位。
27Qcumulative saturation。
26:25IT[1:0]IT位,由IT[7:2]和IT[1:0]组成,Thumb指令集中IT指令的If-Then执行状态。
24J指示ARM是否处于Jazelle状态。
19:16GE[3:0]被一些SIMD(Single Instruction Multiple Data)指令使用。
15:10IT[7:2]见IT[1:0]的描述。
9E指示处理器的大小端模式,同时可以通过设置该位来修改处理器的大小端模式,1表示大端模式,0表示小端模式。
8A是否屏蔽异步终止,该位为1时表示屏蔽异步终止,为0时表示打开异步终止。
7I是否屏蔽IRQ,该位为1时表示屏蔽IRQ,为0时表示打开IRQ。
6F是否屏蔽FIQ,该位为1时表示屏蔽FIQ,为0时表示打开FIQ。
5T指示ARM是否处于Thumb状态。J和T标志共同决定处理器使用的指令集。J=0,T=0:ARM指令集;J=0,T=1:Thumb指令集;J=1,T=0:Jazelle指令集;J=1,T=1:ThumbEE指令集。
4:0M[4:0]指示处理器的模式,同时可以通过设置该位域来修改处理器的模式。

处理器各个模式的编码如下图所示:

在这里插入图片描述

APSR寄存器组成

在用户模式下,用户程序能够操作的CPSR寄存器位域是有限制的,对CPSR寄存器的部分位域屏蔽之后就是APSR了,应用程序状态寄存器(APSR)的位组成如下图所示:

在这里插入图片描述
从上图可以看出,APSR只能访问N,Z,C,V,Q和GE[3:0]这些标志位,这些标志位的含义和CPSR中对应标志位的含义一样。

SPSR

备份程序状态寄存器(Saved Program Status Register,SPSR)主要用于存储前一个执行模式的CPSR。FIQ、IRQ、ABT、SVC和UND模式,都有他们自己模式下专用的SPSR。在处理器发生中断或者异常时,处理器会自动的从一个模式A进入到另一个模式B,模式A的CPSR/APSR将会自动保存到模式B的SPSR中,这样模式B中的处理程序能够通过访问SPSR寄存器得到模式A下CPSR寄存器的信息。

程序状态寄存器操作指令

CPS指令

可以通过CPS(Change Processor State)指令来修改处理器模式。CPS指令也可以用来使能或者禁止异常。

CPS指令的语法如下所示:

CPS #mode
CPSIE iflags{, #mode}
CPSID iflags{, #mode}

mode是处理器的模式编码,比如在从其他模式下切换到SYS模式,使用下述代码即可:

# 切换到SYS模式
CPS #0x1f

IE使能中断或者终止。

ID禁止中断或者终止。

iflags由下面的一种或者几种组成:

  • a:表示异步终止(asynchronous abort);
  • i:表示中断(IRQ);
  • f:表示快中断(FIQ);

下述代码是CPS指令的一些简单用法:

# 使能中断
CPSIE I

# 禁止中断
CPSID I

# 使能异步终止和快中断
CPSIE AF

# 禁止异步终止和快中断
CPSID AF

# 使能中断并切换到SYS模式
CPSIE I, #0x1f

MRS与MSR指令

MRSMSR指令可用于读写程序状态寄存器CPSR,APSR和SPSR。

在ARM处理器中,只有MRS指令可以从程序状态寄存器CPSR,APSR和SPSR中读出数据到通用寄存器中。MRS指令操作程序状态寄存器的语法如下:

MRS{cond} Rd, psr

cond为条件码。

Rd为目标寄存器,Rd不允许为R15。

psr为程序状态寄存器CPSR,APSR或者SPSR。

MRS指令的示例代码如下所示:

# 将CPSR寄存器的值读取到R0中
MRS R0, CPSR

# 将SPSR寄存器的值读取到R1中
MRS R1, SPSR

# 将APSR寄存器的值读取到R2中
MRS R2, APSR

MSR指令可以用来写程序状态寄存器CPSR,APSR和SPSR的全部或者部分域。MSR指令操作程序状态寄存器的语法如下:

MSR{cond} psr, #constant
MSR{cond} psr, Rm
MSR{cond} psr_fields, #constant
MSR{cond} psr_fields, Rm

cond为条件码。

psr为程序状态寄存器CPSR或者SPSR。

constant是一个8位立即数。ARM文档对于constant的介绍如下:

constant is an 8-bit pattern rotated by an even number of bits within a 32-bit word. (Not available in Thumb.)

Rm是源寄存器。

fields由下面的一个或者多个组合而成:

  • c:xPSR[7:0],控制位域;
  • x:xPSR[15:8],扩展位域;
  • s:xPSR[23:16],状态位域;
  • f:xPSR[31:24],标志位域;

MSR指令的示例代码如下所示:

# 切换到SYS模式
MRS R0, CPSR
ORR R0, R0, #0x1f
MSR CPSR, R0

# 切换到SYS模式
MSR CPSR_c, #0xDF

只有在除用户模式外的其他模式下才能够修改状态寄存器

欢迎关注博主的公众号(微信搜索公众号:嵌入式那些事),可以扫描下面的公众号二维码:

在这里插入图片描述
如果文中有什么问题欢迎指正,毕竟博主的水平有限。

如果这篇文章对你有帮助,记得点赞和关注博主就行了^_^。

排版更好的内容见我博客的地址:http://www.only2fire.com/archives/155.html

注:转载请注明出处,谢谢!^_^

<think>嗯,用户问怎么看是不是ARMv7-A。首先,我需要确定用户的具体需求。可能他们在调试或开发过程中遇到了与ARM架构相关的问题,需要确认设备的具体版本。比如,之前的问题涉及DFSR寄存器,可能是在处理异常时需要知道具体的架构版本,以便正确解析寄存器。 接下来,我需要回忆ARM架构的不同版本,特别是ARMv7-A的特点。ARMv7-A是应用级架构,常见于智能手机和嵌入式系统。而ARMv8-A则引入了64位支持,分为AArch64和AArch32两种执行状态。用户可能需要区分ARMv7ARMv8,或者确认设备是否是ARMv7-A。 用户可能的背景是开发者或系统工程师,需要了解硬件架构来适配软件或调试问题。他们可能没有直接访问设备的权限,或者设备信息不明确,所以需要多种方法来确认。 然后,我应该考虑不同的方法来检测ARM版本。比如,查看CPU信息文件、使用命令行工具、读取寄存器,或者通过编程接口。需要详细说明每个步骤,并给出具体的命令或代码示例,确保用户能够实际操作。 另外,要注意不同操作系统下的差异。比如Linux和Android的命令可能不同,或者需要root权限。用户可能在不同的环境中操作,所以需要涵盖多种情况。 还要考虑用户可能遇到的误区,比如/proc/cpuinfo中的信息可能不够详细,或者某些字段的意义需要解释。例如,ARMv8在AArch32状态下可能仍显示为ARMv7,这时候需要进一步检查。 最后,确保回答清晰,分步骤说明,并提供相关问题,帮助用户深入理解。比如,区分ARMv7ARMv8的方法,或者如何通过寄存器判断架构版本。</think>### 专业解释: 要判断设备是否为**ARMv7-A架构**,可通过以下方法验证: --- #### **1. 查看 `/proc/cpuinfo`(Linux系统)** 在Linux终端执行: ```bash cat /proc/cpuinfo ``` - **ARMv7-A特征**: - `Processor` 字段显示类似 `ARMv7 Processor rev 2 (v7l)`。 - `Features` 字段包含 `swp`, `half`, `thumb`, `fastmult`, `vfp`, `edsp`, `neon`, `vfpv3` 等。 - `CPU architecture` 为 `7`。 - **ARMv8-A特征**: - `Processor` 字段显示 `aarch64` 或 `ARMv8 Processor rev 4 (v8l)`。 - `CPU architecture` 为 `8`。 --- #### **2. 使用 `lscpu` 命令** ```bash lscpu ``` - **ARMv7-A输出示例**: ``` Architecture: armv7l CPU(s): 4 Thread(s) per core: 1 Model name: ARMv7 Processor rev 3 (v7l) ... ``` - **ARMv8-A输出示例**: ``` Architecture: aarch64 CPU(s): 8 Thread(s) per core: 1 Model name: ARMv8 Processor rev 0 (v8l) ... ``` --- #### **3. 读取 `MIDR` 寄存器ARM汇编)** 通过读取主ID寄存器(`MIDR_EL1`)获取架构信息: ```c // ARM汇编示例(ARMv7-A) unsigned int midr; asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (midr)); // 解析MIDR字段(ARMv7-A架构ID为0x410FC070-0x410FC07F) if ((midr & 0xFFF0F000) == 0x410FC000) { // ARMv7-A架构 } ``` - **MIDR格式**(ARMv7-A): - `[31:24]`:Implementer(如0x41=ARM Ltd) - `[23:20]`:Architecture(0xF表示ARMv7-A) - `[19:16]`:Variant(芯片版本) - `[3:0]`:Revision(修订号) --- #### **4. 使用 `uname -m` 命令** ```bash uname -m ``` - **ARMv7-A输出**:`armv7l` 或 `armhf`。 - **ARMv8-A输出**:`aarch64`。 --- #### **5. 检查内核日志(dmesg)** ```bash dmesg | grep -i "CPU architecture" ``` - **ARMv7-A日志**:`CPU architecture: 7 (virtualization)`。 - **ARMv8-A日志**:`CPU architecture: 8 (64-bit)`。 --- ### 通俗解释: ARM架构版本就像手机的型号,ARMv7-A是旧款(32位),ARMv8-A是新款(支持64位)。 **通过以下方式快速识别**: 1. **看参数**:`/proc/cpuinfo` 中的 `ARMv7` 或 `aarch64`。 2. **查命令**:`uname -m` 返回 `armv7l` 表示ARMv7-A,`aarch64` 表示ARMv8-A。 3. **读寄存器**:用汇编代码读取 `MIDR`,判断是否为ARMv7-A的标识。 --- ### 核心区别: | 特征 | ARMv7-A | ARMv8-A | |---------------------|--------------------------|--------------------------| | **位宽** | 32位 | 64位(兼容32位) | | **执行状态** | AArch32 | AArch64 + AArch32 | | **寄存器数量** | 16通用寄存器(R0-R15) | 32通用寄存器(X0-X30) | | **虚拟化支持** | 有限 | 完整虚拟化扩展 | | **典型设备** | 旧款智能手机(如骁龙410)| 新款智能手机(如骁龙845)| --- ### 注意项: 1. **ARMv8-A的兼容模式**: ARMv8-A支持运行32位程序(AArch32),此时 `/proc/cpuinfo` 可能显示为 `ARMv7`,需结合 `lscpu` 或 `uname -m` 确认。 2. **交叉编译工具链**: 编译时需指定目标架构(如 `-march=armv7-a` 或 `-march=armv8-a`),避免指令集不兼容。 3. **性能差异**: ARMv8-A的64位模式性能更高(如更多寄存器、NEON改进),但部分旧设备仅支持ARMv7-A。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackailson

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值