142011
 

五、ARM9的中断和异常

1.什么是异常:
        只要正常的程序流程被暂时停止,则异常发生。或者说,异常是由内部或外部产生一个引起处理器处理的事件,例如,外部中断或处理器执行一个未定义的指令都会引起异常。在处理异常之前,处理器状态必须保留,以便在异常处理程序完成后,原来的程序能够重新执行。同一时刻可能会出现多个异常。 

2.ARM9支持的异常类型
        ARM支持7种类型的异常处理,如下表。异常出现后处理器强制从异常类型所对应的固定存储器地址开始执行程序,这些存储器地址称为异常向量(exception vectors)
arm9异常
(1)复位:处理器上一旦有复位信号输入,ARM处理器立刻停止执行当前指令,复位后,ARM处理器在禁止中断的管理模式下,从地址0×00000000或0xFFFF0000开始执行程序。
(2)未定义指令异常:当ARM处理器执行协处理器指令时,它必须等待任一外部协处理器应答后,才能真正执行这条指令。若协处理器没有响应,就会出现未定义指令异常。另外,试图执行未定义的指令,也会出现未定义指令异常。 
(3)软件中断异常:软件中断异常指令SWI进入管理模式,以请求特定的管理函数
(4)预取中止:存储器系统发出存储器中止(abort)信号,响应取指激活的中止标记所取的指令无效,若处理器试图执行无效指令,则产生预取中止异常;若指令未执行,则不发生预取中止。一般由于取指位置没有字对齐引起。

(5)数据中止:存储器系统发出存储器中止信号,响应数据访问激活中止标记的数据无效。一般由于数据地址不是字对齐引起。
(6)IRQ(中断请求):通过处理器上的IRQ输入引脚,由外部产生IRQ异常。IRQ异常的优先级比FIQ异常的低。当进入FIQ处理时,会屏蔽掉IRQ异常。
(7)FIQ(快速中断请求):通过处理器上的FIQ输入引脚,由外部产生FIQ异常。
        补充一点,为什么FIQ能够更快速的响应中断呢,这是由硬件保证的。其一,FIQ模式的R8~R14寄存器都是独立的物理寄存器,所以这些寄存器无需压栈保存,省去了访存的时间;其二,上表中,FIQ的中断向量,无论是正常地址还是高地址,都位于向量表的最后一个,这样可以把中断服务程序直接放在表中,而省去了跳转到响应服务程序地址的时间;其三,由下表的中断优先级可知,FIQ优先级较高。

3.异常优先级


4.异常向量
        异常向量是异常服务程序的入口,在某些ARM的应用中,允许异常向量的位置由32位地址空间低端的正常位置,即0×00000000~0x0000001C,移到地址空间高端的另一地址范围0xFFFF0000~0xFFFF001C。这些改变后的地址位置称为高端向量
由Implementation Defined决定是否支持高端向量。如果支持,则在输入硬件配置时,选择是使用正常向量还是高端向量。 
 

5.异常的进入和退出
        当处理一个异常时,ARM9完成以下动作:
(1)将下一条指令的地址保存在相应的LR寄存器中。如果异常是从ARM状态进入,则保存在LR中的是下一条指令的地址。如果异常是从Thumb状态进入,则保存在LR中的是当前PC的偏移量。
(2)将CPSR复制到相应的SPSR中。
(3)迫使CPSR模式位M[4:0]的值设置成对应的异常模式值
(4)迫使PC从相关的异常向量取下一条指令
(5)也可以设置中断禁止位来阻止其他无法处理的异常嵌套。如果在异常发生时处理器是在Thumb状态下,那么当用中断向量地址加载PC时,自动切换进入ARM状态。

        在完成异常处理后,ARM9完成以下动作:
(1)将LR寄存器的值减去相应的偏移量(偏移量根据异常的不同而不同),送到PC中。
(2)将SPSR复制回CPSR中。
(3)清除中断禁止位标志。
中断返回
 
 
六、ARM9的寻址方式
 
寻址方式是根据指令中给出的地址码字段来寻找真实操作数地址的方式。ARM处理器支持的基本寻址方式有以下几种:
(1)寄存器寻址
        所需要的值在寄存器中,指令中地址码给出的是寄存器编号,既寄存器的内容为操作数。例如指令:
        ADD  R0,R1,R2   ;R0=R1+R2
2) 立即寻址
        立即寻址是一种特殊的寻址方式,指令中在操作码字段后面的地址码部分不是操作数地址,而是操作数本身。例如指令:
        ADD  R3,R3,#1      ;R3=R3+1
        注意,立即数前要加#号
(3) 寄存器移位寻址
        寄存器移位寻址方式是ARM指令集中所特有的,第二个寄存器操作数在与第一个操作数结合之前,选择进行移位操作。例如指令:
        ADD R3,R2,R1,LSL #3;R3=R2+8×R1
        LSL #3 逻辑左移3位,相当于乘以8,被操作寄存器为最后一个位置的寄存器
(4) 寄存器间接寻址
        指令中的地址码给出某一通用寄存器的编号,在被指定的寄存器中存放操作数的有效地址,而操作数则存放在该地址对应的存储单元中,即寄存器为地址指针。例如指令:
        LDR  R0,[R1]                    ;R0=[R1]

        LDR指令用于读取存储器内容至寄存器
(5) 变址寻址
        变址寻址就是将基址寄存器的内容与指令中给出的偏移量相加,形成操作数有效地址。变址寻址用于访问基址附近的单元,包括基址加偏移和基址加索引寻址。寄存器间接寻址是偏移量为0的基址加偏移寻址。
        基址加偏移寻址中的基址寄存器包含的不是确切的地址。基址需加(或减)最大4KB的偏移来计算访问的地址。例如指令:
        LDR R0,[R1,#4]        ;R0=[R1+4]
(6) 多寄存器寻址
       一次可以传送几个寄存器的值,允许一条指令传送16个寄存器的任何子集。例如指令:
       LDMIA R1,{R0,R2,R5}     ;R0=[R1],R2=[R1+4],R5=[R1+8]
       由于传送的数据项总是32位的字,基址R1应该字对准。
(7)堆栈寻址
      堆栈是一种按特定顺序进行存取的存储区,这种特定顺序既是“先进后出”或“后进先出”。堆栈寻址是隐含的,它使用一个专门的寄存器(堆栈指针,就是R13寄存器)指向一块存储器区域。栈指针所指定的存储单元就是堆栈的栈顶。堆栈可分为两种:
      向上生长,又称递增堆栈,既地址向高地址方向生长。
      向下生长,又称递减堆栈,既地址向低地址方向生长。
(8)块拷贝寻址
      块拷贝寻址指令是一种多寄存器传送指令,多寄存器传送指令用于把一块数据从存储器的某一位置拷贝到另一位置。块拷贝指令的寻址操作取决于数据是存储在基址寄存器所指的地址之上还是之下、地址是递增还是递减,并与数据的存取操作有关。
(9)相对寻址
      相对寻址是变址寻址的一种变通,由程序计数器PC提供基地址,指令中的地址码字段作为偏移量,两者相加后得到操作数的有效地址。偏移量指出的是操作数与当前指令之间的相对位置。子程序调用指令既是相对寻址指令。 

 Leave a Reply

(必须填写)

(必须填写,邮件地址不会被泄露)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>