异常入口流程的细节
当异常发生时,以下的情况会随之发生:
1 压栈,并且栈指针更新;
2 处理器取出异常向量并且将其写入PC
3 寄存器更新(LR、IPSR和NVIC寄存器)
压栈
当异常发生时,八个寄存器会被自动压栈
这些寄存器包括R0-R3,R12,R14(链接寄存器),返回地址(下一条指令的地址或程序计数器),程序状态寄存器(xPSR)。
将寄存器R0-R3,R12,PC,LR和xPSR保存到栈中的原因是,这些寄存器被称为“调用者保存寄存器”
使用进程栈PSP——异常发生时处理器处于线程模式并且CONTROL【1】置一,
使用主栈MSP——对于嵌套异常,压栈时总是使用主栈,因为处理器当前处于处理模式,这种情况下只能使用主栈
——异常发生时,处理器处于线程模式,CONTROL【1】为0,使用主栈。
C函数不需要保存这些寄存器的值,为了使异常处理能够像普通C函数一样使用,这些寄存器需要由硬件进行保存和恢复,这样在回到线程模式时,中断前的程序能够正常运行。
栈帧——压栈时保存到栈里的数据。
当压栈结束后,栈指针会得到更新,并且主栈指针会被选择为当前栈指针,处理模式使用的总是主栈MSP,然后异常向量也会被取出。
寄存器的压栈顺序如图
xPSR是组合状态寄存器
其中的三个寄存器之一:IPSR中断程序状态寄存器,包含了当前的中断服务程序(ISR)编号,由此可以取出异常向量。
取出向量并且更新PC
压栈完成以后,处理器会从向量表中取出异常向量,然后将向量写到PC,并且将从这个地址中开始异常处理的取指。