暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

arm基础知识(三)arm寄存器介绍

二进制人生 2020-04-27
2575

微信公众号:二进制人生
专注于嵌入式linux开发。问题或建议,请发邮件至hjhvictory@163.com。
更新:2020/04/26。

内容目录

1.arm寄存器通用寄存器程序状态寄存器2.CPSR寄存器详解CPSR与CPSR_c的区别

本系列文章整理了arm的相关基础知识,内容整理自网络,初衷是想让零散的知识更具体系化和系统化。

从事嵌入式arm开发,还是有必要了解下arm的寄存器。虽然现在不要求会写汇编,但是作为一个资深工程师,我们还是需要有读懂汇编代码的能力。

分析内核代码,也少不了与汇编打交道,而汇编语言和平台架构紧密结合,基本都是在操作寄存器。我们今天来学习下arm寄存器。

1.arm寄存器

ARM 处理器一般共有 37 个寄存器,其中包括:

(1) 31 个通用寄存器,包括 PC(程序计数器)在内,都是 32 位的寄存器。
(2) 6 个状态寄存器,都是 32 位的寄存器。这6个包括1个CPSR,5个不同处理器模式下的SPSR。

需要知道ARM处理器共有7种不同的处理器模式:

用户模式(User),
快速中断模式(FIQ),
普通中断模式(IRQ),
管理模式(Svc),
数据访问中止模式(Abort),
未定义指令中止模式(Und),
系统模式(Sys),

用户进程通常运行于用户模式,通过中断、系统调用、异常进入其他模式。系统模式可以理解为进入内核态。中断模式很容易理解,未定义指令中止模式我举个例子。内核代码有时候怕程内存越界,会在边界处赋值一条不存在的指令值,比如0xdead之类,执行到此处便会陷入未定义指令异常模式。数据访问中止模式最常见的就是访问了不该访问的内存空间,或者是内核时刻在发生的缺页异常。

有点见识的同学可能知道arm的处理器有r0 - r15,其中:

r13又称 sp ,即堆栈寄存器;
r14又称 lr ,即链接寄存器;
r15又称 pc ,即程序计数器。

在汇编代码里通常不会写r13,r14,r15,都会用其别名,因为看起来意思比较明确。

这样算起来只有16个,一般的cpu都会有状态寄存器,还记得51单片机吗,它也有一个程序状态寄存器,叫 PSW 。

程序状态寄存器通常用来保存指令执行后的状态,比如加法操作产生了进位,会置位进位状态位。

arm也有程序状态寄存器,叫 cpsr(current program status register)。还有备份程序状态寄存器,叫spsr。SPSR是用来保存中断前的CPSR中的值,以便在中断返回之后恢复处理器程序状态。

在每一种处理器模式中有一组相应的寄存器。在任意一种处理器模式下,可见的寄存器包括15个通用寄存器(R0~R14)、一个或者二个状态寄存器以及程序计数器(PC)。在所有的寄存器中,有些是各模式共用同一个物理寄存器,有些寄存器是各个模式自己拥有独立的物理寄存器,所以导致arm一共有37个寄存器。任何处理器模式下arm只有一个cpsr,而spsr有多个,不同的异常模式对应一个,由于用户模式(User)和系统模式(sys)不属于异常模式,所以spsr只有5个。

其中 r0~r3 主要用于子程序间传递参数, r4~r11 主要用于保存局部变量,但在 Thumb 程序中,通常只能使用 r4~r7 来保存局部变量;r12 用作子程序间scratch寄存器,即 ip 寄存器;r13 通常用做栈指针,即 sp;r14 寄存器又被称为连接寄存器(lr),用于保存子程序以及中断的返回地址;r15 用作程序计数器(pc),由于 ARM 采用了流水线机制,当正确读取了 PC 的值后,该值为当前指令地址加8个字节,即 PC 指向当前指令的下两条指令地址。

总结一下,这37个寄存器如下:

通用寄存器

知道r0-r7为啥叫不分组寄存器了吧,因为任何模式下只有1个。需要注意的是,分组寄存器只有在处于相应的模式下才能使用,比如r13_abt,只有处于数据访问中止模式下才能使用。

程序状态寄存器

2.CPSR寄存器详解

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

我们来看下这32位的程序状态寄存器究竟保存了哪些状态。

(1)条件码标志

N、Z、C、V,最高4位称为条件码标志。ARM的大多数指令可以条件执行的,即通过检测这些条件码标志来决定程序指令如何执行。

各个条件码的含义如下:

N:在结果是有符号的二进制补码情况下,如果结果为负数,则N=1;如果结果为非负数,则N=0。

Z:如果结果为0,则Z=1;如果结果为非零,则Z=0。

C:其设置分一下几种情况:

           对于加法指令(包含比较指令CMN),如果产生进位,则C=1;否则C=0

           对于减法指令(包括比较指令CMP),如果产生借位,则C=0;否则C=1

           对于有移位操作的非法指令,C为移位操作中最后移出位的值。

           对于其他指令,C通常不变。

V:对于加减法指令,在操作数和结果是有符号的整数时,如果发生溢出,则V=1;如果无溢出发生,则V=0;对于其他指令,V通常不发生变化。

(2)控制位的作用在图中可以看出,在这里就不阐述了。

CPSR与CPSR_c的区别

  CPSR_c指的是CPSR的低8位控制位

  CPSR有4个8位区域:标志域(F)、状态域(S)、扩展域(X)、控制域(C

  C 控制域屏蔽字节(psr[7:0])
  X 扩展域屏蔽字节(psr[15:8])
  S 状态域屏蔽字节(psr[23:16])
  F 标志域屏蔽字节(psr[31:24])

所以我们在看到cpsr_cxsf时不要惊讶,它其实就是cpsr。

cpsr和spsr指令比较特殊,只能用msr和mrs这两条指令进行操作,用于在状态寄存器和通用寄存器之间传送数据。如:

mrs r0, cpsr ;读取cpsr中的值  
bic r0, r0, #0x1F ;修改,去除当前处理器模式  
orr r0, r0, #0x13 ;修改,设置特权模式  
msr cpsr_c, r0 ;写回,仅仅修改CPRS中的控制位  

关于这两条指令我们点到即止,不做过多介绍,网上有很多文章。


每天进步一点点……

图 二进制人生公众号




文章转载自二进制人生,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论