在ARM体系中,通常有以下3种方式控制程序的执行流程:
1、在正常执行过程中,每执行一条ARM指令,程序计数器PC的值加4个字节;每执行一条Thumb指令,程序计数器PC加2个字节。整个过程是顺序执行的;
2、跳转 B指令执行跳转操作;BL指令在执行跳转的同时,保存子程序返回地址;BX指令,执行跳转的同时,根据目标地址的最低位,可以将程序状态切换到Thumb状态;BLX指令执行上述3个操作;
3、当异常中断发生时,系统执行完当前指令后,将跳转到相应的异常中断处理程序处执行。在进入异常中断处理程序时,要保存被中断的程序的执行现场,在从异常中断处理程序退出时,要恢复被中断的程序的执行现场。当异常中断处理程序执行完成后,程序返回到发生中断的指令的下一条指令处执行。
异常中断种类、异常中断向量地址和异常中断优先级别见下表:
ARM运行的几种处理器模式如上表所示。其中,应用程序通常运行在用户模式下!
为了说明异常中断执行过程,先了解各处理器模式下的寄存器组,如下表:
重点:ARM处理器对异常中断的响应过程:
㈠、保存当前程序状态寄存器CPSR到对应异常中断的处理器模式下的SPSR中;
㈡、设置当前程序状态寄存器CPSR的处理器模式位M(4:0)为对应的处理器模式,并禁止IRQ中断(设置I位=1);当进入的是FIQ模式时,禁止FIQ中断(设置F位=1);
㈢、将对应异常中断的处理器模式下的LR设置成返回地址;
㈣、将程序计数器PC值,设置成该异常中断向量地址,从而跳转到相应的异常中断处理程序处执行。
上述处理器对异常中断的响应过程可以用伪代码描述如下:
R14<exception_mode>=return Link
SPSR<exception_mode>=CPSR
CPSR[4:0]=exception mde number
CPSR[5] = 0 //所有异常均在ARM状态下处理(本句出自《基于ARM的嵌入式系统开发与实例》P32)
if(<exception_mode>==Reset or FIQ )then
CPSR[6]=1 //禁止FIQ中断
CPSR[7] =1 //禁止IRQ中断
PC = exception vetor address
程序将自动跳转到对应异常中断的处理程序中。
上述过程,完全由处理器自动完成,所以,当发生一种异常中断时,寄存器R14 、CPSR、SPSR和PC的值将是上述的结果!结果如下图所示:
下面是引用别人的文章:
ARM处理器中主要有7个异常(2个中断异常):
1、复位异常;在以ARM为核的单片机中,常把下列事件作为引起复位的原因。
? 上电复位:在上电后,复位使内部达到预定的状态,特别是程序跳到初始入口;
? 复位引脚上的复位脉冲:这是由外部其他控制信号引起的;
? 对系统电源检测发现过压或欠压;
? 时钟异常复位。
ARM处理器复位后,处理器硬件将进行以下操作:
? 强制进入管理模式;0b10011
? 强制进入ARM状态;T=0
? 跳转到绝对地址PC=0x00000000处执行;
? 禁止IRQ中断和FIQ中断。I=1,F=1;
复位后,程序状态寄存器如下:
...... I F T M4 M3 M2 M1 M0
1 1 0 1 0 0 1 1
上电复位后,进入管理模式,执行操作系统程序,一般用做对系统初始化,例如开中断等;然后切换到用户模式,开始执行正常的用户程序。
切换到用户模式可使用下列程序:
MRS R0,CPSR ;读状态寄存器
BIC R0,R0,#03 ;把末两位清0
MSR CPRS_c,R0 ;把修改后的值加载给状态寄存器,切换结束
...... ;用户程序
2、未定义指令异常;由于ARM使用32位代码,包含的信息量很大,可达2的31方(4G)。ARM指令集不能用尽所有代码。当ARM处理器遇到无法译码的指令时就会发生未定义指令异常。进入中断处理程序。
ARM的未定义指令异常有以下两种情况:
(1)遇到一条无法执行的指令,此指令没有定义;
(2)执行一条对协处理器的操作指令,在正常情况下,协处理器应该应答,但协处理器没有应答。
未定义异常中断时,处理器硬件将进行以下操作:
? 把下一条指令的地址拷贝给LR;
? 把程序状态寄存器CPSR拷贝给SPSR_und;
? 强制进入未定义模式; 0b11011
? 强制进入到ARM模式;T=0
? 跳转到绝对地址PC=0x00000004处执行;
? 禁止IRQ中断。 I=0
? 状态寄存器中的F位不变。
进入中断后,程序状态寄存器如下:
...... I F T M4 M3 M2 M1 M0
1 x 0 1 1 0 1 1
使用下列指令退出异常中断,返回原程序 。
MOVS PC,R14.
3、软件中断异常;是由指令SWI引起的。程序在执行这一指令后,进入异常中断。
{下面是《ARM体系结构与编程》书中的一段摘录}
********SWI和未定义指令异常中断是由当前执行的指令自身产生的。当SWI和未定义指令异常中断产生时,程序计数器PC的值还未更新,它指向当前指令后面第2条指令(对于ARM指令来说+8字节;对于Thumb指令来说+4字节的位置)。当SWI和未定义指令异常中断产生时,处理器将值(PC-4)保存到异常模式下的寄存器LR_mode中。这时(PC-4)即指向当前指令的下一条指令地址。因此返回操作可以通过下面的指令来实现:MOV PC,LR
该指令将寄存器LR中的值复制到程序计数器PC中实现程序返回,同时将SPSR_mode寄存器内容复制到当前程序状态寄存器CPSR中。**********{摘录结束}
处理器响应中断,硬件执行如下的操作。
? 把下一条指令的地址拷贝给LR;
? 把程序状态寄存器CPSR拷贝给SPSR_svc;
? 强制进入管理模式;0b10011
? 强制进入到ARM状态;T=0
? 跳转到绝对地址PC=0x00000008处执行;
? 禁止IRQ中断。 I=1; F保持不变;
进入中断后的程序状态寄存器如下:
...... I F T M4 M3 M2 M1 M0
1 x 0 1 0 0 1 1
软件中断处理程序完成后,使用下列指令返回到原中断处:MOVS PC,R14.
4、预取指中止异常;由程序存储器引起的中止异常叫做预取指中止异常;由数据存储器引起的中止异常叫做数据中止异常。由于ARM的指令是3级流水线结构,读取指令周期是提前进行的,因此把读取指令的过程一般称预取指。如果在取得指令的同时程序存储器发出中止信号,则ARM处理器把这一条指令标记位无效,然后等待执行。
{下面是《ARM体系结构与编程》书中的一段摘录}
************在指令预取时,如果目标地址是非法的,该指令将被标记成有问题的指令。这时,流水线上该指令之前的指令继续执行。当执行到该被标记成有问题的指令时,处理器产生指令预取中止异常中断。
当发生指令预取中止异常中断时,程序要返回到该有问题的指令处,重新读取并执行该指令。因此指令预取中止异常中断程序应该返回到产生该指令预取中止异常中断的指令处,而不是像前面两种情况下返回到发生中断的指令的下一条指令。
指令预取中止异常中断是由当前执行的指令自身产生的,当指令预取中止异常中断产生时,程序计数器PC的值还未更新,它指向当前指令后面第2条指令(对于ARM指令来说,它指向当前指令地址加8个字节的w位置;对于Thumb指令来说,它指向当前指令地址加4个字节的位置)。当指令预取中止异常中断产生时,处理器将(PC-4)值保存到异常模式下的寄存器LR_mode中。这时(PC-4)即指向当前指令的下一条指令。因此返回操作可以通过下面的指令来实现:SUBS PC,LR,#4
该指令将寄存器LR中的值减4后,复制到程序计数器PC中,实现程序返回,同时将SPSR_mode寄存器内容复制到当前程序状态寄存器CPSR中。*************{摘录结束}
有两种可能如下:
? 当执行这条指令前程序发生跳转,则这条无效指令不引起异常中断;
? 当执行到这条指令时,处理器会发生预取指中止异常,引起中断。
当进入预取指异常中断时,处理器硬件响应中断,执行以下的操作:
? 把中断时PC的地址拷贝给LR;
? 把程序状态寄存器CPSR拷贝给SPSR_abt;
? 强制进入中止异常模式;0b10111
? 强制进入到ARM状态;T=0;
? 跳转到绝对地址PC=0x0000000C处执行;
? 禁止IRQ中断。 I=1;
进入中断后,程序状态寄存器如下:
...... I F T M4 M3 M2 M1 M0
1 x 0 1 0 1 1 1
预取指中止异常中断返回时,应该执行下列指令:SUBS PC,R14,#4.
5、数据中止异常;ARM处理器访问数据存储器时,在读取数据的同时数据存储器发出了中止信号,引起数据中止异常。
当进入预取数据异常中断时,处理器硬件响应中断,执行以下的操作:
? 把中断时的PC的地址拷贝给LR;
? 把程序状态寄存器CPSR拷贝给SPSR_abt;
? 强制进入中止异常模式;
? 强制进入到ARM状态;
? 跳转到绝对地址PC=0x00000010处执行;
? 禁止IRQ中断。
进入中断后,程序状态寄存器如下:
...... I F T M4 M3 M2 M1 M0
1 x 0 1 0 1 1 1
数据中止异常中断服务程序返回时,使用下列指令:SUBS PC,R14,#8
上述指令是返回到中断时所执行的指令,目的是再一次从数据存储器中读取数据。如果不再一次读取数据,则执行下一条指令,此时使用下列指令返回: SUBS PC,R14,#4
6、中断请求(IRQ)异常;例如:定时器中断、串行口通讯中断、外部信号中断和A/D处理中断等。IRQ中断是可屏蔽的。
{下面是《ARM体系结构与编程》书中的一段摘录}P269
************ 通常当处理器执行完当前指令后,查询IRQ中断引脚及FIQ中断引脚,并且查看系统是否允许IRQ及FIQ中断。如果有中断引脚有效,并且系统允许该中断产生,处理器将产生IRQ或FIQ异常中断。这时,程序计数器PC的值已经更新,它指向当前指令后面的第3条指令(对于ARM指令来说,它指向当前指令地址+12字节位置;对于Thumb指令来说,它指向当前指令地址+6字节的位置)。处理器这时将值(PC-4)保存到异常模式下的寄存器LR_mode中。这时(PC-4)即指向当前指令后面的第2条指令。因此返回操作可以通过下面的指令实现: SUBS PC, LR, #4
该指令将寄存器LR中的值减4后,复制到程序计数器PC中,实现程序返回,同时将SPSR_mode寄存器内容复制到当前程序状态寄存器CPSR中。**********{摘录结束}
在状态寄存器中的I位就是IRQ的屏蔽位
。当I=1时。则屏蔽IRQ中断,当I=0时,则允许中断。处理器复位后置I为1,关闭中断。
当发生IRQ中断时,处理器硬件响应中断,执行下列操作:
? 把中断时的PC的地址值拷贝给LR;
? 把程序状态寄存器CPSR拷贝给SPSR_irq;
? 强制进入IRQ异常模式;
? 强制进入到ARM状态;
? 跳转到绝对地址PC=0x00000018处执行;
? 禁止IRQ中断。
进入中断后,程序状态寄存器如下:
...... I F T M4 M3 M2 M1 M0
1 x 0 1 0 0 1 0
完成中断处理后,程序执行下列返回原中断处:SUBS PC.R14,#4.
7、快速中断(FIQ)请求异常;FIQ快速中断是可屏蔽的。在状态寄存器中的F位就是FIQ的屏蔽位。当F=1时。则屏蔽FIQ中断,当F=0时,则允许中断。处理器复
位后置F为1,关闭中断。
当发生FIQ中断时,处理器硬件响应中断,执行下列操作:
? 把中断时的PC的地址值拷贝给LR;
? 把程序状态寄存器CPSR拷贝给SPSR_fiq;
? 强制进入FIQ异常模式;
? 强制进入到ARM状态;
? 跳转到绝对地址PC=0x0000001C处执行;
? 禁止FIQ中断。
进入中断后,程序状态寄存器如下:
...... I F T M4 M3 M2 M1 M0
1 x 0 1 0 0 0 1
完成中断处理后,程序执行下列返回原中断处:SUBS PC.R14,#4