先来了解一下ARM的7种工种模式:
1、一上电,cpu处于SVC模式
2、发生中断
cpu进入IRQ模式;
R13、R14切换到自己的R13、R14;
跳到0X18去执行;
3、碰到一条机器码CPU不认识
cpu进入UND模式;
R13、R14切换到自己的R13、R14;
跳到0X4去执行;
4、bl print_cpsr
print_cpsr(unsigned int cpsr, char *why) //第一个参数是r0,第二个是r1
5、SWI #val
cpu进入SVC模式;
R13、R14切换到自己的R13、R14;
跳到0X8去执行;
6、异常在写程序时有什么用?
SWI: App:open,read,... 其实是一条swi 指令,被调用时就会发生异常,而进入内核空间,就会根据后面的参数,加以判断而调用内核的相应函数。
UND:一般用于调试。
对应视频中的代码:19th_cpsr
1>start.S 中添加了各个异常的入口地址
软件上:1)在地址8,放一条跳转指令;2)保存现场; 3)处理异常; 4)恢复现场。
1、一上电,cpu处于SVC模式
2、发生中断
cpu进入IRQ模式;
R13、R14切换到自己的R13、R14;
跳到0X18去执行;
3、碰到一条机器码CPU不认识
cpu进入UND模式;
R13、R14切换到自己的R13、R14;
跳到0X4去执行;
4、bl print_cpsr
print_cpsr(unsigned int cpsr, char *why) //第一个参数是r0,第二个是r1
5、SWI #val
cpu进入SVC模式;
R13、R14切换到自己的R13、R14;
跳到0X8去执行;
6、异常在写程序时有什么用?
SWI: App:open,read,... 其实是一条swi 指令,被调用时就会发生异常,而进入内核空间,就会根据后面的参数,加以判断而调用内核的相应函数。
UND:一般用于调试。
对应视频中的代码:19th_cpsr
1>start.S 中添加了各个异常的入口地址
_start:
/* 0 地址 */
b reset /* 复位时,cpu跳到0地址 */
ldr pc, =undefined_instruction /* cpu遇到不能识别的指令时 */
ldr pc, _vector_swi /* 当执行swi指令时, 进入SVC模 式 */
@ldr pc, _prefetch_abort /* 预取中止异常 */
@ldr pc, _data_abort /* 数据访问异常 */
@ldr pc, _not_used /* 没用到 */
@ldr pc, _irq /* 中断异常 */
@ldr pc, _fiq /* 快中断异常 */
_vector_swi:
.word vector_swi
vector_swi:
/* 1. 保存现场 */
ldr sp, =0x56000000 /* sp,r13, r13_svc */
stmdb sp!, {r0-r12, lr} /* lr就是swi的下一条指令地址 */
/* 2. 处理异常 */
mrs r0, cpsr
ldr r1, =swi_str
bl print_cpsr
/* 3. 恢复现场 */
ldmia sp!, {r0-r12, pc}^ /* ^表示把spsr恢复到cpsr */
swi_str:
.word 0x00697773 /* swi */
在代码中故意放了一条swi指令,当执行到这个swi时,我们看看硬件上和软件上分别要做什么事情? 硬件上:1)CPU进入SVC模式;2)CPSR状态更新--》SPSR_svc;3)切换到SVC自己的R13,R14; 4)下一条指令存于R14; 5)跳转异常地址8软件上:1)在地址8,放一条跳转指令;2)保存现场; 3)处理异常; 4)恢复现场。