标题:
ARM 异常处理过程讲解(2)
[打印本页]
作者:
look_w
时间:
2017-9-24 17:39
标题:
ARM 异常处理过程讲解(2)
我们知道在
ARM
架构里,
PC
值指向当前执行指令的地址加
8
处,也就是说,
当执行指令
A
(地址
0x8000
)时,
PC
等于指令
C
的地址(
0x8008
)。假如指令
A
是
“BL”
指令,则当执行该指令时,会把
PC
(
=0x8008
)保存到
LR
寄存器里面,但是接下去处理器会马上对
LR
进行一个自动的调整动作:
LR=LR-0x4
。这样,最终保存在
LR
里面的是
B
指令的地址,所以当从
BL
返回时,
LR
里面正好是正确的返回地址。同样的调整机制在所有
LR
自动保存操作中都存在,比如进入中断响应时,处理器所做的
LR
保存中,也进行了一次自动调整,并且调整动作都是
LR=LR-0x4
。
下面,我们对不同类型的异常的返回地址依次进行说明:
假设在指令
A
处(地址
0x8000
)发生了异常,进入异常响应后,
LR
上经过调整保存的地址值应该是
B
的地址
0x8004
。
1
、
如果发生的是软件中断,即
A
是
“SWI”
指令
异常是由指令本身引起的,从
SWI
中断返回后下一条执行指令就是
B
,正好是
LR
寄存器保存的地址,
所以只要直接把
LR
恢复给
PC
。
MOVS pc, lr
2
、
发生的是
Undefined instruction
异常
异常是由指令本身引起的,从异常返回后下一条执行指令就是
B
,正好是
LR
寄存器保存的地址,
所以只要直接把
LR
恢复给
PC
。
MOVS pc, lr
3
、
发生的是
IRQ
或
FIQ
中断
因为指令不可能被中断打断,所以
A
指令执行完以后才能响应中断,此时
PC
已更新,指向指令
D
的地址(地址
0x800C
),
LR
上经过调整保存的地址值是
C
的地址
0x8008
。中断返回后应该执行
B
指令,所以返回操作是:
SUBS pc, lr, #4
4
、
发生的是
Prefetch Abort
异常
该异常并不是处理器试图从一个非法地址取指令时触发,取出的指令只是被标记为非法,按正常处理流程放在流水线上,在执行阶段触发
Prefetch Abort
异常,此时
LR
上经过调整保存的地址值是
B
的地址
0x8004
。异常返回应该返回到
A
指令,尝试重新取指令,所以返回操作是:
SUBS pc, lr, #4
5
、
发生的是
“Data Abort”
CPU
访问存储器时触发该异常,此时
PC
指向指令
D
的地址(地址
0x800C
),
LR
上经过调整保存的地址值是
C
的地址
0x8008
。异常返回后,应回到指令
A
,尝试重新操作存
储器,所以返回操作是:
SUBS pc, lr, #8
以上就是
ARM
异常的
CPU
操作部分,接下来就是程序员应该完成的操作。
1.
由于
CPU
会自动跳转到对应的异常向量中,因此只需要在在各个异常向量中存放对应的操作,最简单的都是存放一个
B
指令跳转到对应的异常处理函数的操作即可。但由于
B
指令的跳转返回只有
+-32M
,而异常处理函数的地址可能会超过
+-32M,
因此可以采用另一种方式实现方式:
在异常向量中保存一条指令
LDR PC [addr],
其中的
addr
中就保存了异常处理函数的地址,当然
addr
的相对地址要小于
+-32M
。这样也就解决了跳转范围的问题。
2.
接下来就是异常处理函数对应的操作,可以在进入异常处理之前就进行返回地址的调整,这样后面就不用进行处理啦,当然也可以在返回过程中再调整。一般都是在这个过程中进行调整。进行压栈操作,保存对应的环境变量。调用实际的处理过程等。
3.
出栈,恢复
CPU
的状态和寄存器的值。由于第一步中已经调整好返回地址,这一步不需要再次调整。当然如果之前没有调整,这里则需要进行相应的调整。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0