1. 异常/中断的基本知识介绍
异常/中断是ARM经常用到的处理机制,因此需要好好学习。这里总是写中断/异常是因为中断属于异常的一种,而我们经常听到中断这个词语而少听到异常这个词,所以这些特意写成中断/异常。如果CPU发生中断时,我说CPU发生了异常,你可不能说我讲错了,因此异常包含了中断。
1.1 ARM的7种工作模式
从2440的数据手册中可以看到,ARM920T(2440使用的ARM920T的核) 总共有7种工作模式
模式 | 作用 |
---|---|
用户模式 | ARM正常的工作模式 |
快速中断模式 | 用来支持数据传输或通道处理 |
中断模式 | 通常的中断处理 |
管理模式 | 用来保护操作系统 |
中止模式 | 在指令或数据处理出错时进入 |
系统模式 | 操作系统在模式下有一些特权操作 |
未定义模式 | 当执行未定指令时进入此模式 |
其中的中断模式就是我们常用的中断 ,当ARM处理中断操作时,就进入此模式。
1.2 ARM的异常向量表
当ARM发生异常时,就会把PC的值设置成一个固定的值,让程序跳转到固定的地址执行程序,并进入相应的工作模式。
如:
当发生复位时,PC=0x0, 程序跳转到0地址去执行程序,并进入管理模式。
当发生中断时,PC=0x18, 程序跳转到0x18地址去执行程序,并进入中断模式。
上面的例子中,PC的值由硬件自动帮忙赋值,不需要软件来操作。
从这里可以看出来,想要进入不同的工作模式,就需要发生不同的异常。这里就找到了异常与工作模式的关系。
1.3 重要的寄存器CPSR
如何知道ARM当前处于什么模式呢? 可以通过查看CPSR(Current Program States Register )寄存器来知道。
CPSR寄存器的bit[0] ~ bit[4] 可以查出ARM当前工作模式。
不过CPSR这种特殊的寄存器不是一般的mov指令可以操作的, 要通过msr,和 mrs来完成对CPSR寄存器的读写。
如
//读取cpsr 到r0
mrs r0, cpsr
//清空r0的低4位
bic r0, r0, #0xf
//把r0赋值给cpsr
msr cpsr, r0
1.4 异常/中断的处理过程
在处理异常/中断时,即有硬件的处理也有软件的处理,主要的流程如下:
-
某种条件发引起异常
-
发生异常时硬件的处理,即进入异常
2.1将返回地址保存在LR(R14)寄存器
2.2将CPSR复制到SPSR(SPSR 就是专门弄来备份CPSR的)
2.3设置CPSR的模式位(设置CPSR的bit0~bit4)
2.4设置PC值为对应的中断/异常向量表(跳到固定地址) -
发生异常时软件的处理,即处理异常然后回到异常发生时的位置继续处理
3.1 设置SP(因为需要通过压栈来保存寄存器和代码跳转)
3.2 保存现场(将通用的寄存器保存起来)
3.3 将SPSR赋值给CPSR
3.4 清除中断标志位(针对中断)
3.5 恢复现场(将通用的寄存器恢复回去)
3.6 将LR减去对应的值,再赋值给PC
3.6 将LR减去对应的值,在赋值给PC, 在2440手册中有表格说明LR的值,不过每种模式下LR的值是如何计算的并没有找到说明。
1.5 不同工作模式下的私有寄存器
ARM 通用的寄存器有R0-R15,不过在不同的工作模式下会有一些自己的私有寄存器。
如:
在FIQ模式下,会用到R0-R15,但是R8_fiq-R14_fiq虽然也是叫R8-R14,不过这是FIQ模式下的私有寄存器,不会影响到通用的R8-R14
在Supervisor模式下,会用到R0-R15,但是R13_svc-r14_srv虽然也叫R13-R14, 不过这是Supervisor模式下的私有寄存器,不会影响到通用的R13-R14
综上,用2句话来总结一下
- 他们是在不同模式下才有的私有寄存器
- 因为他们的功能时相同的,所以取名也相同,实际上是不同的物理寄存器
1.6 总结
看完后需要对以下的几个问题有些基本的了解才行。
- ARM总共有几种工作模式
- ARM有多少种异常
- 异常与工作模式之间有什么关系
- 在执行完异常后,如何计算LR的返回地址