简介
ARM体系中,CPU有七种工作模式:
模式的切换可以通过软件控制,即改写CPSR(current program status register)寄存器。也可以通过发生异常(中断是异常的一种),硬件触发进入相应模式。
关于不同模式
不同的模式,拥有的一些不同的寄存器。
图中,有三角标号的即是自己模式下的寄存器,没有三角标号的则是公用的寄存器。可以看出在快中断模式下,备份寄存器较多,减少了备份的时间,故而快速。
另外,在这里有个常识,即R0~R12是普通的工作寄存器,而R13~R15则比较特殊,R13是栈指针寄存器(每个模式都有自己的栈指针),R14是连接寄存器,R15是程序计数器。即R13是我们常说的SP,R14是LR,R15是PC。
关于CPSR寄存器
一般更改状态只需要对低八位进行控制即可。
关于异常中断的流程
1. 发生异常
发生异常时,CPU会自动做这些事(举例:当从模式1换到模式2):
①将模式1即将执行的下一条指令地址(即模式1的PC+4),放入模式2的LR寄存器。
②将模式1的CPSR的值赋到SPSR中。(备份)
③将CPSR设置成模式2。
④令PC等于这个异常模式的入口地址,(即跳转入中断处理函数)
前两点是备份,后两点是切换模式。
除此之外,我们还要手动对现场进行保存,即比如把公用的寄存器(如R0~R12)和LR放入堆栈中。
2. 执行中断服务函数
ISR是用C语言写的,执行到最后还要对相关寄存器的中断标志请求清除,INTPND,SRCPND寄存器两个。部分中断还需要对EINTPEND寄存器进行清除。
3.退出异常
当然,在退出异常模式的时候,我们就要手动做这些事情
1.把之前保存在模式2 LR寄存器中的指令(模式1的下一条工作指令),放入PC中。
2.把之前保存在盏中的东西取出
3.将SPSR的值复制回CPSR
疑问:
1 HandleIRQ: 2 sub lr, lr, #4 @ 1. count the back address 3 stmdb sp!, {r0-r12,lr} @ 2. keep the register and the lr 4 ldr lr, =int_return @ 3. set call back fuction 5 ldr pc, =EINT_Handle @ 4. call ISR fuction 6 int_return: 7 ldmia sp!, {r0-r12,pc}^ @ '^'mean give cpsr from spsr
1.第2行 :lr为何要减4 ,尝试过不减4,返回需要一段时间
2.第5、6行 :为何执行完EINT_Handle后,会继续执行int_return。 lr会自动赋值给pc?