i.mx6ull中断向量表部分代码如下:
疑问:在_start中,汇编代码具体是如何执行和跳转的(越具体越好,从下面的代码分析)?ldr pc, =label是否会被执行?
我的理解:
①程序必然执行第一行ldr pc, =Reset_Handler,随后跳转到Reset_Handler中,并最终通过b main跳转到main函数
②剩余的ldr pc,=label 不会被执行,但编译器会给到这些指令相应的程序地址(0x04、0x08、0x0C),用于发生中断时跳转到相应的程序地址去执行中断函数
.global _start
_start:
ldr pc, =Reset_Handler /* Reset */
ldr pc, =Undefined_Handler /* Undefined instructions */
ldr pc, =SVC_Handler /* Supervisor Call */
ldr pc, =PrefAbort_Handler /* Prefetch abort */
ldr pc, =DataAbort_Handler /* Data abort */
.word 0 /* RESERVED */
ldr pc, =IRQ_Handler /* IRQ interrupt */
ldr pc, =FIQ_Handler /* FIQ interrupt */
Reset_Handler:
cpsid i /* 全局关闭中断 */
mrc p15, 0, r0, c1, c0, 0 /*读取CP15系统控制寄存器 */
bic r0, r0, #(0x1 << 12) /* 清除第12位(I位)禁用 I Cache */
bic r0, r0, #(0x1 << 2) /* 清除第 2位(C位)禁用 D Cache */
bic r0, r0, #0x2 /* 清除第 1位(A位)禁止严格对齐 */
bic r0, r0, #(0x1 << 11) /* 清除第11位(Z位)分支预测 */
bic r0, r0, #0x1 /* 清除第 0位(M位)禁用 MMU */
mcr p15, 0, r0, c1, c0, 0 /* 将修改后的值写回CP15寄存器 */
/* 定义IRQ工作模式的栈起始地址 */
cps #0x12
ldr sp, =IRQ_model_stack_start
/*定义User工作模式的栈起始地址,与Supervisor相同*/
cps #0x1F
ldr sp, =SUP_model_stack_start
/*定义Supervisor工作模式的栈起始地址,与User相同 */
cps #0x13
ldr sp, =SUP_model_stack_start
/*跳转到系统初始化函数,初始化GIC、CACHE-L1、mmu等等*/
ldr r2, =SystemInit
blx r2
/*开启全局中断*/
cpsie i
/*跳转到到 main 函数执行,*/
b main
b . /*死循环*/