赞
踩
ARM共有如下7种异常模式:
当异常发生时,CPU会主动将PC赋值为低地址或高地址,该地址处有一条指令用于处理该类型异常,我们将存储这些指令的地方称为异常中断向量表。ARM规定每个向量占用4字节空间(通常会放一个跳转指令或一个向PC寄存器赋值的数据访问指令。通过这两种指令,将程序跳转到相应的异常中断处理程序处执行),共32个字节。
异常发生时,ARM会将处理其切换到对应的模式来处理异常。此外,不同种类的异常有可能会同时发生,此时ARM会按照一定的优先级策略来处理这些异常。
上述相关的信息见下表所示。
图中未定义指令与软件中断异常的优先级都是6,这其实没有关系,因为这两类异常不可能同时发生。
要实际处理上述七种异常,需要软硬件的协同,这里记录的是硬件对异常的处理步骤,并不涉及软件部分。在实际编程过程中,只有首先明白硬件对异常处理逻辑后,才能正确的进行软件处理。
硬件对异常的处理分为两部分:发生异常时的处理(进入部分)和异常结束处理(离开部分),而且无论是哪种异常,硬件对它们的处理过程大致相同,只有个别的细节不同,下面首先讨论共性,然后再具体类型具体说明。
当异常发生时,处理器大致按照如下的流程进行处理:
上述过程用伪代码表示为:
- R14_<exception_mode> = return link
- SPSR_<exception_mode> = CPSR
- CPSR[4:0] = exception mode number
- CPSR[5] = 0 //异常处理时处理器一定是工作在ARM状态的
- if <exception_mode> == Reset or FIQ then
- CPSR[6] = 1 //有条件的屏蔽FIQ中断
- CPSR[7] = 1 // 总是屏蔽IRQ中断
- PC = exception vector address
- R14_svc = UNPREDICTABLE value
- SPSR_svc = UNPREDICTABLE value
- CPSR[4:0] = 0b10011 // 复位异常在特权模式下运行
- CPSR[5] = 0
- CPSR[6] = 1 // 关闭FIR和IRQ中断
- CPSR[7] = 1
- if high vectors configured then
- PC = 0xFFFF0000
- else
- PC = 0x00000000
注意:复位异常的处理是不需要返回的,所以其R14和SPSR的值是未定义的。
- R14_und = PC - 4
- SPSR_und = CPSR
- CPSR[4:0] = 0b11011 // 处理器进入未定义指令模式
- CPSR[5] = 0
- CPSR[7] = 1 // 只禁止IRQ,FIQ不变
- if high vectors configured then
- PC = 0xFFFF0004
- else
- PC = 0x00000004
- R14_svc = PC - 4
- SPSR_svc = CPSR
- CPSR[4:0] = 0b10011 // 处理器进入特权模式
- CPSR[5] = 0
- CPSR[7] = 1 // 只禁止IRQ,FIQ不变
- if high vectors configured then
- PC = 0xFFFF0008
- else
- PC = 0x00000008
- R14_abt = PC - 4
- SPSR_abt = CPSR
- CPSR[4:0] = 0b10111 // 处理器进入中止模式
- CPSR[5] = 0
- CPSR[7] = 1 // 只禁止IRQ,FIQ不变
- if high vectors configured then
- PC = 0xFFFF000C
- else
- PC = 0x0000000C
- R14_abt = PC - 4
- SPSR_abt = CPSR
- CPSR[4:0] = 0b10111 // 处理器进入中止模式
- CPSR[5] = 0
- CPSR[7] = 1 // 只禁止IRQ,FIQ不变
- if high vectors configured then
- PC = 0xFFFF0010
- else
- PC = 0x00000010
- R14_irq = PC - 4
- SPSR_irq = CPSR
- CPSR[4:0] = 0b10010 // 处理器进入IRQ模式
- CPSR[5] = 0
- CPSR[7] = 1 // 只禁止IRQ,FIQ不变
- if high vectors configured then
- PC = 0xFFFF0018
- else
- PC = 0x00000018
- R14_fiq = PC - 4
- SPSR_fiq = CPSR
- CPSR[4:0] = 0b10001 // 处理器进入FIQ模式
- CPSR[5] = 0
- CPSR[6] = 1 // 禁止FIQ、IRQ
- CPSR[7] = 1
- if high vectors configured then
- PC = 0xFFFF0018
- else
- PC = 0x00000018
当异常处理结束后,需要执行如下两步操作才能返回到被异常中断的地方继续执行:
由于这两种异常是在指令执行过程中发生的,此时PC指向当前指令后面的第二条指令(对于ARM状态为当前指令地址加8,对于THUMB状态为当前指令地址加4),因为在中断发生时,处理器将PC-4的结果保存到了lr_mode中,所以在返回时,只需要直接将lr_mode的值复制到PC中即可。
因为对IRQ和FIQ的处理是在一条指令结束时发生的,此时PC的值指向当前指令后面的第三条指令(对于ARM状态为当前指令地址加12,对于THUMB状态为当前指令地址加6),因为在中断发生时,处理器将PC-4的结果保存到了lr_mode中,所以在返回时,需要将lr_mode-4的结果赋值给PC。
指令预取中止异常虽然在指令的取址阶段就发生了,但是真正对该异常的处理是在执行该指令时发生的,此时PC的值指向当前指令后面的第二条指令(对于ARM状态为当前指令地址加8,对于THUMB状态为当前指令地址加4)。该异常的处理结束返回时,应该返回到产生该异常的指令地址处重新执行该指令,而不是返回到产生该异常的指令的下一条指令处执行。因为在中断发生时,处理器将PC-4的结果保存到了lr_mode中,所以在返回时,需要将lr_mode-4的结果赋值给PC。
发生该异常时,PC指向当前指令后面的第三条指令(对于ARM状态为当前指令地址加12,对于THUMB状态为当前指令地址加6)。同样的,对该异常的处理返回时,应该返回到产生该异常的指令地址处重新执行该指令。因为在中断发生时,处理器将PC-4的结果保存到了lr_mode中,所以在返回时,需要将lr_mode-8的结果赋值给PC。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。