目录
一、寄存器的概念
1、什么是寄存器?
2、寄存器的分类
3、不同工作模式下使用的寄存器
二、常见专用寄存器
1、R15(PC,Program Counter)
2、R14(LR,Link Register)
3、R13(SP,Stack Pointer)
三、控制寄存器CPSR
1、模式位 Bit[4:0]
2、状态位 Bit[5]
3、FIQ使能位 Bit[6] / IRQ使能位 Bit[7]
4、判断是否进位/借位 Bit[28] —— 有符号数运算
5、判断是否进位/借位 Bit[29] —— 无符号数运算
6、判断运算结果是否为 0 Bit[30]
7、判断运算结果是否为负 Bit[31]
寄存器是CPU内部的存储器,没有地址。一般用于暂时存放参与运算的数据和结果,比如CPU在做加法运算的时候,加数、被加数以及产生的结果都是暂存在寄存器里。
寄存器分为三种类型,分别是通用寄存器、专用寄存器、控制寄存器。
通用寄存器指的是没有指定用途,可以存放任意内容的寄存器。既可以存放地址,也可以存放参与运算的数据或者运算产生的结果。
专用寄存器指的是有着指定用途,只能存放指定内容的寄存器。比如程序计数器PC 用于存放下一个要执行的指令的地址、SP用于存放栈顶元素的地址。
控制寄存器指的是用于控制当前CPU运行状态或者运算状态的寄存器。比如CPSR寄存器用于可以用于控制CPU当前所处工作模式,以及保存运算时的进位状态。
看下面这个图的时候要以列为单位观察,每一列代表一种工作模式,不同工作模式使用的寄存器也不尽相同。不带三角形符号的表示不同工作模式之间可以共用的寄存器,如r0~r7是所有工作模式都可以共用的寄存器;带三角形符号的表示某一工作模式下特有的寄存器,其他工作模式无法使用该寄存器。
注意:图中虽然看着有很多寄存器,但实际上很多寄存器是可以共用的,算上共用和特有寄存器,一个处理器中仅有40个寄存器。
程序计数器,用于存储当前取址指令的地址。我们写的程序在经过预处理、编译、汇编以后,得到的二进制机器码就是指令。这些指令是被保存在内存中的,CPU接下来要执行哪一条指令都是由PC控制的。
我们写程序时的逻辑是顺序执行,那么CPU在执行指令的时候也是如此,在ARM状态下,每一条指令都占4个字节,所以每执行完一条指令,PC的值会自动自增4个字节,为下一次取指令做准备
链接寄存器,也是保存指令地址,一般是发生跳转的时候,事先保存跳转指令下一条指令的地址,一般有两种用途。
假设main函数在执行程序的时候,需要调用函数func(),这个时候会跳转到func() 函数的定义。由于执行完func()函数以后还要继续运行main函数,在跳转之前LR寄存器会保存func()函数下一条指令的地址,也就是printf函数的地址。
在执行完func函数以后,只需要让 PC = LR 就可以回到func()函数下一条指令的地址。
产生异常时,异常模式下的LR会自动保存被异常打断的指令的下一条指令的地址。(也可以理解成是一种函数跳转)
比如CPU正在忙手里的任务,突然收到了网卡发来的信号,CPU就会进入FIQ或者IRQ模式,此时CPU就会停下手里的任务,转而先去执行异常处理程序。异常处理结束后将LR的值复制到PC可实现程序返回。
栈指针,用于存储当前模式下的栈顶地址。假设现在CPU要将运算结果保存到栈上,这个时候SP寄存器就会告诉CPU栈顶的位置在哪,保存完毕以后,SP指向的地址会更新。
CPSR(Current Program Status Register)是当前程序状态寄存器。可以控制处理器当前所处工作模式,可以保存运算状态,如进位、借位。
用于控制处理器所处的工作模式。不同工作模式对应的取值如下:
工作模式 | 取值(左边高位,右边低位) |
User | 10000 |
FIQ | 10001 |
IRQ | 10010 |
SVC | 10011 |
Abort | 10111 |
Undef | 11011 |
System | 11111 |
Monitor | 10110 |
表示当前处理器所处状态。ARM状态下,每一条指令占4个字节,PC每次自增4;Thumb状态下,每一条指令占2个字节,PC每次自增2。
处理器状态 | 取值 |
ARM状态 | 0(默认状态) |
Thumb状态 | 1 |
Bit[6] 表示是否开启FIQ,默认状态是开启。
FIQ状态 | 取值 |
开启 | 0(默认状态) |
关闭 | 1 |
Bit[7] 表示是否开启 IRQ,默认状态是开启。
IRQ状态 | 取值 |
开启 | 0(默认状态) |
关闭 | 1 |
该位记录的是,当参与运算的是有符号数时,运算是否发生了进位或者借位,这里要把加法和减法分开讨论。
该位记录的是,当参与运算的是无符号数时,运算时是否发生了进位或者借位,同样要把减法和减法分开讨论。
当运算结果为 0 时,该位自动置 1,否则为 0
当运算结果为负数时,该位自动置 1,否则为 0