⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 except.s

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 S
📖 第 1 页 / 共 3 页
字号:
        ADD   r0, r0, #Angel_RegBlock_R0offset + (8*4)        STMIA r0, {r8-r12}      ; r8-r12 are not banked between USR and UND        ADD   r0, r0, #(13*4) - (8*4)      IF :DEF: STRONGARM_REV1OR2        MCR   MMUCP, 0, r0, c0, c0, 0      ENDIF        STMIA r0, {r13,r14}^    ; Store out the USR r13 and r14        SUB   r0, r0, #Angel_RegBlock_R0offset + (13*4)RegsNowSaved        ; We have to check that the undefined instruction we hit        ; was indeed the Angel Undefined instruction        ;        ; Clearly this uses different code for Thumb and ARM states        ; but make the Thumb support code removable        ;        ; Note that r14_und has been adjusted to point to the undef        ; (ARM or Thumb).        IF :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT<>0          MRS   r0, SPSR          TST   r0, #Tbit          BEQ   CompareWithARMBreakPoint                     LDRH  r0, [r14]       ; load the Thumb instruction          MOV   r1, #angel_BreakPointInstruction_THUMB :AND: 0xff00          ORR   r1, r1, #angel_BreakPointInstruction_THUMB :AND: 0xff          CMP   r0, r1          BNE   UnrecognisedInstruction          BEQ   NormalBreakpoint ; Skip over the check for Vector Hit case        ENDIFCompareWithARMBreakPoint        LDR     r0, [r14]        ; load the ARM instruction        LDR     r1, =angel_BreakPointInstruction_ARM        CMP     r0, r1        BNE     UnrecognisedInstruction                ; We now know it is Angel's Undefined instruction        ; r0 = r1 = The undefined instruction        ; lr = address of the undefined instruction        ; spsr = unchanged        ; sp  = FD UND stack (currently empty)BreakPointInstruction        ; We must check to see if it is a special case - a breakpoint        ; in DefaultExceptionTable, which actually means it is an        ; exception (there are no real handlers for the other exceptions).        ;        ; This little piece of code only every has to deal with ARM undefs        LDR     r0, =DefaultExceptionTable        SUB     r1, r14, r0     ; r1 = addr of Breakpoint - start of table        MOV     r1, r1, ASR #2  ; r1 is now the index into DefaultExceptionTable        CMP     r1, #7        BGT     NormalBreakpoint ; Not in this table        CMP     r1, #0        BLT     NormalBreakpoint ; Not in this table        B       VectorHitNormalBreakpoint        ; This is executed for both an ARM and Thumb breakpoint        LDR    r2, =ADP_Stopped_BreakPointCallSerialiseTask        ; Now prepare to call Angel_SerialiseTask        ; r0 and r2 are set up by caller        ;        ; SerialiseTask expects:        ; r0 = called_by_yield        ; r1 = fn        ; r2 = type (already set up)  ; r3 = empty_stack        MOV   r0, #0        LDR   r1, =angelOS_ThreadStopped        MOV   r3, sp        B     Angel_SerialiseTask        ; and angelOS_ThreadStopped will execute when SerialiseTask        ; allows it toUnrecognisedInstruction        LDR   r2, =ADP_Stopped_UndefinedInstr        B     CallSerialiseTaskVectorHit        ; r1 is the index into the DefaultExceptionTable.        ; sp = UND sp - currently empty        ;        ; If this is a data abort, and Angel was in the process of        ; performing a data access, which aborted then we must        ; unwind the abort and return to that code, setting a flag        ; so it knows what has happened.        ;        ; In all other cases just report the problem to the debugger.        CMP   r1, #4            ; Data Abort vector        BNE   ReportToDebugger        IMPORT  memory_is_being_accessed        IMPORT  memory_access_aborted        IMPORT  angel_StartTask_NonSVCEntry                LDR   r0, =memory_is_being_accessed        LDR   r0, [r0]        CMP   r0, #0        BEQ   ReportToDebugger  ; Not due to Angel Aborting!        ; Now we know that it is either angelOS_MemRead or angelOS_MemWrite        ; that has aborted.  These both run in User32 mode, and if aborted        ; then we went into Abort32 mode, storing the real pc, cpsr        ; in the abort regs.  This will in turn have gone through the        ; table of undefined instructions and hence got into under32 mode,        ; which is where we are now.  Thus we have to read the Abort regs        ; and put them into the saved register block and then restart        ; using that block.        ; Indicate an abort has happened        LDR   r0, =memory_access_aborted        MOV   r1, #1        STR   r1, [r0]                ; Get into abort mode        MRS   r1, CPSR        BIC   r1, r1, #ModeMask        ORR   r1, r1, #ABTmode        MSR   CPSR_cxsf, r1        LDR   r0, =Angel_MutexSharedTempRegBlocks        ; We have to get r13 and r14 from the USR bank !        ADD   r1, r0, #Angel_RegBlock_R0offset + (4*13)      IF :DEF: STRONGARM_REV1OR2        MCR   MMUCP, 0, r0, c0, c0, 0      ENDIF        STMIA r1, {r13,r14}^    ; USR bank version                ; Put SPSR, and pc into the saved registers block        ; Adjust PC by 4 - This relies on MemRead / MemWrite being written        ; in ARM code not Thumb code.        SUB   r2, r14, #4         STR   r2, [r0, #Angel_RegBlock_R0offset + (4*15)] ; original pc        MRS   r2, SPSR        STR   r2, [r0, #Angel_RegBlock_CPSRoffset] ; original cpsr        B     angel_StartTask_NonSVCEntry                ReportToDebugger                LDR   r2, =ADP_Stopped_BranchThroughZero        ADD   r2, r2, r1        B     CallSerialiseTask  ENDIF ; End of ICEMAN_LEVEL_3        IMPORT Angel_SerialiseTask                        DefaultExceptionTable        DCD     angel_BreakPointInstruction_ARM ; 00 - Reset        DCD     angel_BreakPointInstruction_ARM ; 04 - Undefined instructions        DCD     angel_BreakPointInstruction_ARM ; 08 - SWI instructions        DCD     angel_BreakPointInstruction_ARM ; 0C - Instruction fetch aborts        DCD     angel_BreakPointInstruction_ARM ; 10 - Data access aborts        DCD     angel_BreakPointInstruction_ARM ; 14 - Reserved        DCD     angel_BreakPointInstruction_ARM ; 18 - IRQ interrupts        DCD     angel_BreakPointInstruction_ARM ; 1C - FIQ interrupts        ; *************************************************************        ; See discussion above HandlerUndef for limitations which also        ; apply to this handler.        ; in: SVC mode; IRQs disabled; FIQs undefined        ;     r13 = FD stack        ;     r14 = address of SWI instruction + 4        ;     All other registers must be preserved                IMPORT  angelOS_SemiHostingEnabled                EXPORT HandlerSWIHandlerSWI        STMFD sp!, {r0}        ; Disable interrupts        MRS   r0, CPSR        IF (FIQ_SAFETYLEVEL >= FIQ_NeverUsesSerialiser_DoesNotReschedule)          ORR r0, r0, #IRQDisable        ELSE          ORR r0, r0, #IRQDisable + FIQDisable        ENDIF        MSR   CPSR_cxsf, r0        NOP                ; Save the state of the callee (can be any mode) into a regblock        ; This means r0-r15, and cpsr         ; Can do r0-r7, pc, cpsr for all modes        LDR   r0, =Angel_MutexSharedTempRegBlocks        ADD   r0, r0, #Angel_RegBlock_R0offset + (1*4)        STMIA r0, {r1-r7}       ; r1-r7 are never banked        SUB   r0, r0, #Angel_RegBlock_R0offset + (1*4)        LDMFD sp!, {r1}        STR   r1, [r0, #Angel_RegBlock_R0offset] ; original r0        MRS   r1, SPSR        STR   r1, [r0, #Angel_RegBlock_CPSRoffset] ; original cpsr        IF :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT<>0          TST   r1, #Tbit          SUBEQ r14, r14, #4      ; Adjust for ARM instruction          SUBNE r14, r14, #2      ; Adjust for Thumb instruction        ELSE          SUB   r14, r14, #4      ; Adjust to point to the SWI        ENDIF        STR   r14, [r0, #Angel_RegBlock_R0offset + (15*4)] ; pc        ; Accessing other modes depends on the mode        AND   r1, r1, #ModeMask        CMP   r1, #USRmode        BEQ   SWIWasInUSRMode        CMP   r1, #SYSmode        BEQ   SWIWasInUSRMode        ; Deal with non USR mode case        IF (FIQ_SAFETYLEVEL >= \            FIQ_NeverUsesSerialiser_DoesNotReschedule_HasNoBreakpoints)          ORR r1, r1, #IRQDisable        ELSE          ORR r1, r1, #IRQDisable + FIQDisable        ENDIF        MSR   CPSR_cxsf, r1          ; Now we are in the appropriate mode        ADD   r0, r0, #Angel_RegBlock_R0offset + (8*4)        STMIA r0, {r8-r14}      ; r8-r12 may be banked - now saved        SUB   r0, r0, #Angel_RegBlock_R0offset + (8*4)        MRS   r2, SPSR        STR   r2, [r0, #Angel_RegBlock_SPSRoffset]        ; Get back into SVC        BIC   r1, r1, #ModeMask        ORR   r1, r1, #SVCmode        MSR   CPSR_cxsf, r1        B     RegsNowSaved2SWIWasInUSRMode        ADD   r0, r0, #Angel_RegBlock_R0offset + (8*4)        STMIA r0, {r8-r12}      ; r8-r12 are not banked between USR and SVC        ADD   r0, r0, #(13*4) - (8*4)      IF :DEF: STRONGARM_REV1OR2        MCR   MMUCP, 0, r0, c0, c0, 0      ENDIF        STMIA r0, {r13,r14}^    ; Store out the USR r13 and r14        SUB   r0, r0, #Angel_RegBlock_R0offset + (13*4)RegsNowSaved2        ; r0 = &Angel_MutexSharedTempRegBlocks[0]        ; r1,r2, = corrupt        ; r3-r12 unmodified        ; r13 = SVC stack        ; r14 = adjusted to point to SWI        ; We have to check that the SWI we hit was indeed the Angel SWI        ;        ; Clearly this uses different code for Thumb and ARM states        ; but make the Thumb support code removable        IF :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT<>0          MRS   r2, SPSR          TST   r2, #Tbit          BEQ   CompareWithARMSWI                  LDRH  r2, [r14]       ; load the Thumb instruction          MOV   r1, #angel_SWI_THUMB :AND: 0xff00          ORR   r1, r1, #angel_SWI_THUMB :AND: 0xff          CMP   r2, r1          BNE   UnrecognisedSWI          BEQ   AngelSWI        ENDIFCompareWithARMSWI        LDR     r2, [r14]        ; load the ARM instruction        BIC     r2, r2, #0xFF000000 ; Only compare the SWI numbers        LDR     r1, =angel_SWI_ARM        BIC     r1, r1, #0xFF000000 ; Only compare the SWI numbers        CMP     r2, r1        BNE     UnrecognisedSWI        AngelSWI        ; We now know it is our SWI, so we have to interpret the reason code        ; which was in r0.        ;        ; Here we assume that r0 still addresses regblock        ;        LDR     r1, [r0, #Angel_RegBlock_R0offset] ; original r0  IF (:LNOT: :DEF: MINIMAL_ANGEL) :LOR: MINIMAL_ANGEL = 0        ; Only recognise the C Library SWIs if Semihosting is enabled        LDR     r2, =angelOS_SemiHostingEnabled        LDR     r2, [r2]        CMP     r2, #0  IF :DEF: ICEMAN_LEVEL_3        ; We quietly ignore CLib codes, so first carry on as if semihosting...  ELSE        BEQ     NonCLibReasonCode  ENDIF

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -