ARM中断返回PC值分析

6 篇文章 0 订阅

ARM中断返回PC值分析

在ARM程序的开发过程中,对中断的处理是很普遍的、也是相当重要的。Realview MDK使用的RVCT编译器提供了__irq关键字,用此关键字修饰的函数被作为中断来函数编译,即在编译的过程中,编译器会自动添加中断处理过程中现场保护和恢复的代码,减小程序的开发难度,加快软件的开发过程。

在理解__irq关键字的作用之前,先看一下ARM核对异常的处理过程。当产生异常时, ARM核拷贝CPSR寄存器的内容SPSR_<mode>寄存器中,同时设置适当的CPSR 位、改变处理器状态进入ARM 态和处理器模式,从而进入相应的异常模式。在设置中断禁止位禁止相应中断(如果需要)后,ARM核保存返回地址到LR_<mode>,同时设置PC为相应的异常向量。当异常返回时, 异常处理需要从SPSR_<mode>寄存器中恢复CPSR的值,同时从LR_<mode>恢复PC,具体的异常返回指令如下:

Ø 从SWI和Undef异常返回时使用:

MOVS PC, LR;

Ø 从FIQ、IRQ和预取终止返回时使用:

SUBS PC, LR,#4;

Ø 从数据异常返回时使用:

SUBS PC, LR,#8

在使用上述指令异常返回时,如果LR之前被压栈的话使用LDM “”, 例如:

LDMFD SP!, {PC}

退出异常处理

SWI和未定义指令异常中断是由当前执行的指令自身产生的。当SWI和未定义指令异常中断产生时,程序计数器PC的值还未更新,它指向当前指令后面第2条指令(对于ARM指令来说+8字节;对于Thumb指令来说+4字节的位置)。当SWI和未定义指令异常中断产生时,处理器将值(PC-4)保存到异常模式下的寄存器LR_mode中。这时(PC-4)即指向当前指令的下一条指令地址。因此返回操作可以通过下面的指令来实现:MOV PC,LR

该指令将寄存器LR中的值复制到程序计数器PC中实现程序返回,同时将SPSR_mode寄存器内容复制到当前程序状态寄存器CPSR中。

在指令预取时,如果目标地址是非法的,该指令将被标记成有问题的指令。这时,流水线上该指令之前的指令继续执行。当执行到该被标记成有问题的指令时,处理器产生指令预取中止异常中断。

当发生指令预取中止异常中断时,程序要返回到该有问题的指令处,重新读取并执行该指令。因此指令预取中止异常中断程序应该返回到产生该指令预取中止异常中断的指令处,而不是返回到发生中断的指令的下一条指令。

指令预取中止异常中断是由当前执行的指令自身产生的,当指令预取中止异常中断产生时,程序计数器PC的值还未更新,它指向当前指令后面第2条指令(对于ARM指令来说,它指向当前指令地址加8个字节的w位置;对于Thumb指令来说,它指向当前指令地址加4个字节的位置)。当指令预取中止异常中断产生时,处理器将(PC-4)值保存到异常模式下的寄存器LR_mode中。这时(PC-4)即指向当前指令的下一条指令。因此返回操作可以通过下面的指令来实现:SUBS PC,LR,#4

该指令将寄存器LR中的值减4后,复制到程序计数器PC中,实现程序返回,同时将SPSR_mode寄存器内容复制到当前程序状态寄存器CPSR中。

发生数据访问异常中断时,程序要返回到该有问题的指令处,重新访问该数据,因此数据访问异常中断应该返回到产生该数据访问中止异常中断的指令处,而不是当前指令的下一条指令。

数据访问异常中断由当前执行的指令自身产生,当数据访问异常中断发生时,程序计数器pc的值已经更新,它指向当前指令后面第3条指令(对于ARM指令,它指向当前指令地址加12字节的位置;对于Thumb指令,它指向当前指令地址加6字节的位置)。此时处理器将值(pc-4)保存到lr_abt中,它指向当前指令后面第2条指令,所以返回操作可以通过下面指令实现:subs pc, lr, #8

该指令将lr中的值减8后传给程序计数器pc中,实现程序返回,同时将SPSR_abt寄存器内容复制到当前程序状态寄存器CPSR中;

通常处理器执行完当前指令后,查询IRQ中断引脚,并查看是否允许IRQ中断,如果某个中断引脚有效,并且系统允许该中断产生,处理器将产生IRQ异常中断,当IRQ异常中断产生时,程序计数器pc的值已经更新,它指向当前指令后面第3条指令(对于ARM指令,它指向当前指令地址加12字节的位置;对于Thumb指令,它指向当前指令地址加6字节的位置),当IRQ异常中断产生时,处理器将值(pc-4)保存到IRQ异常模式下的寄存器lr_irq中,它指向当前指令之后的第2条指令,因此返回操作可以通过下面指令实现:subs pc, lr, #4

与IRQ异常中断一样,处理器执行完当前指令后,查询FIQ中断引脚,并查看是否允许FIQ中断,如果中断引脚有效,并且系统允许该中断产生,处理器将产生FIQ异常中断,当FIQ异常中断产生时,程序计数器pc的值已经更新,它指向当前指令后面第3条指令(对于ARM指令,它指向当前指令地址加12字节的位置;对于Thumb指令,它指向当前指令地址加6字节的位置),当FIQ异常中断产生时,处理器将值(pc-4)保存到IRQ异常模式下的寄存器lr_fiq中,它指向当前指令之后的第2条指令,因此返回操作可以通过下面指令实现:subs pc, lr, #4

 

 

ARM指令是三级流水线
就是说取指,译指,执行时同时执行的
这样说吧,现在PC指向的是正在取指的地址,那么cpu正在译指的指令地址是PC-4(假设在ARM状态下,一个指令占4个字节),cpu正在执行的指令地址是PC-8.
也就是说PC所指向的地址和现在所执行的指令地址相差8

当突然发生中断的时候,保存的是PC的地址
这样你就知道了,如果返回的时候返回PC,那么中间就有一个指令没有执行
所以用SUB pc lr-irq #4,

 

 

 

 

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值