一个DataAbort异常的触发过程:
//////xxxx.inc_STACK_BASEADDRESS EQU 0x33ff8000_MMUTT_STARTADDRESS EQU 0x33ff8000_ISR_STARTADDRESS EQU 0x33ffff00
///xxx.s
MACRO$HandlerLabel HANDLER $HandleLabel$HandlerLabel sub sp,sp,#4 ;decrement sp(to store jump address) stmfd sp!,{r0} ;PUSH the work register to stack(lr does t push because it return to original address) ldr r0,=$HandleLabel;load the address of HandleXXX to r0 ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR) MEND HandlerPabort HANDLER HandlePabortHandlerPabort HANDLER HandlePabort 展开:{HandlerPabort sub sp,sp,#4 ;decrement sp(to store jump address) stmfd sp!,{r0} ;PUSH the work register to stack(lr does''t push because it return to original address) ldr r0,=$HandlePabort ;load the address of HandleXXX to r0 ldr r0,[r0] ;load the contents(service routine start address) of Handler function str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)}
///xxx.s
/* ^ 其实就是 MAP ,这段程序的意思是,从 _ISR_STARTADDRESS 开始,预留一个变量,每个变量一个标号,预留的空间为 4个字节,也就是 32BIT,其实这里放的是真正的C写的处理函数的地址,说白了,就是函数指针*/ ^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00HandleReset # 4HandleUndef # 4HandleSWI # 4HandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ # 4HandleFIQ # 4///
xxxx.c#define _ISR_STARTADDRESS 0x33ffff00 #define pISR_PABORT (*(unsigned *)(_ISR_STARTADDRESS+0xc))pISR_PABORT=(unsigned)HaltPabort; //给PABORT中断入口函数指针赋值。 【 *PABORTFUNC = HaltPabort 】/中断触发时:
1 -- ldr r0,=HandlePabort 2 -- (*(unsigned *)HandlePabort) 即是pISR_PABORT3 -- pISR_PABORT 即是异常处理函数HaltPabort4 -- POP 出栈时弹出的是HandlePabort 到PC