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

📄 except.s

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 S
📖 第 1 页 / 共 3 页
字号:
        ; Now we know semihosting is switched on        LDR     r2, =angel_SWIreason_CLibBase        CMP     r1, r2        BCC     NonCLibReasonCode     ; orig r0 < angel_SWIreason_CLibBase        LDR     r2, =angel_SWIreason_CLibLimit        CMP     r1, r2        BHI     NonCLibReasonCode     ; orig r0 > angel_SWIreason_CLibLimit  IF :DEF: ICEMAN_LEVEL_3        ; ..and now we know it is a CLib code, return immediately        MOV     r0, #1          ; r0 = 1 as a dummy return code        ADD     r14, r14, #4    ; readjust r14, iceman is never in Thumb mode        MOVS    pc, r14  ELSE        ; carry on with CLib processing...                    ; Now we know it is a CLib SWI        IMPORT  SysLibraryHandlerSysLibraryCall        LDR     r2, =SysLibraryHandler        ; Fall through to DoIndirectCall ...  ENDIF  ELSE                          ; minimal angel        B       NonCLibReasonCode  ENDIF                ; We expect the SVC stack to be empty        ; r2 contains the address of the function to be called indirectly        ;        ; We have to leave the SVC stack empty and also finish with        ; regblock before switching mode, as this will (almost definitely)        ; enable interrupts which can blow away the SVC stack.        ; However, we can put stuff on the callers stack temporarily!        ;        ; So we put the caller's CPSR, caller's r1-r3, caller's lr        ; and the address of the instruction after the SWI on the        ; application stack.        ; We can then restore all the potentially unbanked registers        ; and execute the indirectly called functionDoIndirectCall        IMPORT Angel_StackBase                ; Set up caller's stack        LDR     r3, [r0, #Angel_RegBlock_R0offset + (13*4)]        MRS     r6, SPSR        ; original CPSR        ADD     r0, r0, #Angel_RegBlock_R0offset + (1*4)        LDMIA   r0, {r7-r9}     ; original r1-r3        SUB     r0, r0, #Angel_RegBlock_R0offset + (1*4)        LDR     r10, [r0, #Angel_RegBlock_R0offset + (14*4)] ; caller's lr        IF :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT<>0          TST   r6, #Tbit          ADDEQ r11, r14, #4      ; RE-Adjust for ARM instruction          ADDNE r11, r14, #2      ; RE-Adjust for Thumb instruction        ELSE          ADD   r11, r14, #4      ; RE-Adjust to point after SWI        ENDIF        STMFD   r3!, {r6-r11}     ; Put them on callers Stack      IF :DEF: STRONGARM_REV1OR2        MCR     MMUCP, 0, r0, c0, c0, 0      ENDIF        STMFD   r3, {r13,r14}^    ; Put USR r13 and r14 on Stack        MOV     r6, #USRmode      ; We call the fn in USR mode (32 bit code)        SUB     r3, r3, #8        MSR     SPSR_cxsf, r6                        ; Set up USR r13 and r14 for the indirectly called function        STR     r3, [r0, #Angel_RegBlock_R0offset + (13*4)] ; callers r13        LDR     r3, =ApplicationModeIndirectReturnVeneer        STR     r3, [r0, #Angel_RegBlock_R0offset + (14*4)] ; callers r14        ADD     r0, r0, #Angel_RegBlock_R0offset + (13*4)                LDMIA   r0, {r13,r14}^  ; Load the USR r13 and r14 (!!!)        SUB     r0, r0, #(13*4) ; wind back to r0        ; Force the SVC stack to use the Angel SVC stack, no matter        ; what it was before.        LDR     r13, =Angel_StackBase        LDR     r13, [r13]        ADD     r13, r13, #Angel_SVCStackOffset                ; The problem here is that all angel SWI C code is compiled as        ; swst so it needs a valid r10 as a stack limit check.        ; If someone has used r10 as a general purpose register they will        ; have destroyed this functionality and will cause Angel to fail        ; We must put a valid sl in r10 at this point        ; The first thing we must do is take a local copy of the user r10        ; from the stored copy of the user stack (in r0)        LDR     r10, [r0, #(10*4)] ; r10 from the stack        LDR     r11, =SavedR10   ; get the address of the local variable        STR     r10, [r11]      ; and store it there                ; Restore r0-r12 (unbanked regs) - keeping fn to call in r14        MOV     r14, r2        LDMIA   r0, {r0-r12}        STMFD   sp, {r13}^      ; bring in the User Stack pointer        LDR     r10, [sp,#-4]        SUB     r10, r10, #Angel_SVCStackSize ; put the limit at the size        ; We now have a valid sl for Angel to use - The user info is        ; reinstated in ReturnSVC                ; And leap into the indirectly called routine in USR mode        MOVS    pc, lr               ; This gets called when the indirectly called fn returns        ; we will have eight values on the stack (nearest first):         ;  * r13,r14 for USR Mode prior to the indirectly called        ;    fn.  This is only needed if the CPSR at the time        ;    of the SWI was NOT USR.        ;  * CPSR at time of SWI        ;  * r1-r3 values to reinstate        ;  * LR value to reinstate        ;  * address of instruction after the SWI (return there!)        ; This veneer has to return to either ARM or Thumb code        ; depending on what the CPSR on the stack indicates.  It also        ; needs to be able to return to USR or SVC mode code, but is        ; entered always in USR mode.        ; Note that we want to restore the PSR flags on return too.ApplicationModeIndirectReturnVeneer           ; See if SWI was not from USR mode        ; If so restore USR mode r13, r14 after getting into proper mode        LDR   r1, [sp, #8]      ; Get saved CPSR        AND   r1, r1, #ModeMask        CMP   r1, #USRmode        CMPNE r1, #SYSmode        ADDEQ sp, sp, #8        BEQ   AnyModeReturn        ; Non USR mode case - we need to gain privileged mode again        LDR   r1, [sp, #8]      ; Get saved CPSR        MOV   r2, r0        MOV   r3, sp        LDR   r0, =angel_SWIreason_EnterSVC        DCD   angel_SWI_ARM        ;; Response to MLS 1965 to ensure that thumb SWI calls return        ;; correctly when not called from user mode        IF :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT <> 0          BIC   r1, r1, #Tbit   ; Ensure we don't switch in Thumb Mode        ENDIF                MSR   CPSR_cxsf, r1          ; Switch into desired mode        MOV   r0, r2        MOV   sp, r3            ; Restore stack        LDMFD sp, {r13, r14}^   ; Restore USR mode r13 and r14        NOP        ADD   sp, sp, #8AnyModeReturn        LDR     r14, [sp, #0]    ; Get saved CPSR        IF :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT<>0          TST   r14, #Tbit        ENDIF        ADD     sp, sp, #4      ; Finished with the cpsr on the stack        LDMFD   sp!, {r1-r3}    ; Restore old r1-r3        ; Here we must retain the applications r10 if sl wasn't being used        ; so we must get it back from the saved location                LDR     r10, =SavedR10   ; we must reinstate the app r10        LDR     r10, [r10]      ; get it from the saved location                IF :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT<>0          BEQ   ARMCodeReturn          MSR   cpsr_f, lr      ; Restore flags          LDMFD sp!, {lr}       ; Restore old lr          STMFD sp!, {r0}       ; Need a work register (must be r0-r7 - not r14)          ADR   r0, SwitchToThumbLabel+1          BX    r0SwitchToThumbLabel          CODE16          POP   {r0, pc}          CODE32          ALIGN        ENDIFARMCodeReturn                MSR   cpsr_f, lr        ; Restore flags        LDMFD   sp!, {lr, pc}   ; Return to ARM code                        ; **********************************************************        ; Deal with cases other than the semi-hosted CLib SWI        ; r0 = our regblock with the saved regs stored        ; r1 = the original r0 when we get hereNonCLibReasonCode        LDR     r2, =angel_SWIreason_EnterSVC        CMP     r1, r2        BEQ     ReturnSVC        IF (:LNOT: :DEF: MINIMAL_ANGEL) :LOR: MINIMAL_ANGEL = 0          IF :LNOT: (:DEF: JTAG_ADP_SUPPORTED :LOR: :DEF: ICEMAN_LEVEL_3)            LDR     r2, =angel_SWIreason_ApplDevice            CMP     r1, r2            BEQ     ApplDeviceSWI          ENDIF        ENDIF        IF :DEF: LATE_STARTUP :LAND: LATE_STARTUP <> 0          LDR     r2, =angel_SWIreason_LateStartup          CMP     r1, r2          BEQ     LateStartupSWI        ENDIF        LDR     r2, =angel_SWIreason_ReportException        CMP     r1, r2        BNE     UnrecognisedSWI        ; Fall through to ReportException        ReportException  IF :DEF: ICEMAN_LEVEL_3 :LOR: (:DEF: MINIMAL_ANGEL :LAND: MINIMAL_ANGEL<>0)        ; We cannot report an exception within ICEMan        B       ReportException  ELSE        ; The ADP_Stopped code was in r1 before the SWI happened        LDR     r2, [r0, #Angel_RegBlock_R0offset + (1*4)]        B       CallSerialiseTask  ENDIFReturnSVC        ; The SVC stack is empty.  We have to return in SVC mode with        ; IRQ and FIQ disabled. r0-r13 and r14 should be reinstated from        ; regblock (ie. the stack remains the caller's stack)        ; Execution will resume from the instruction after the SWI        ;        ; We will return with r0 set to the address of Angel_ExitToUser        ;         LDR     r2, [r0, #Angel_RegBlock_R0offset + (13*4)] ; get callers sp        LDR     r3, [r0, #Angel_RegBlock_R0offset + (15*4)] ; PC (pts to SWI)        MRS     r4, SPSR        IF :DEF: THUMB_SUPPORT :LAND: THUMB_SUPPORT<>0          TST   r4, #Tbit          ADDEQ r3, r14, #4      ; RE-Adjust for ARM instruction          ADDNE r3, r14, #2      ; RE-Adjust for Thumb instruction        ELSE          ADD   r3, r14, #4      ; RE-Adjust to point after UNDEF         ENDIF        STMFD   sp!, {r2-r3}    ; Push Caller sp and pc onto SVC stack        ; Restore r1-12 and r14        ADD     r0, r0, #Angel_RegBlock_R0offset + (1*4)        LDMIA   r0, {r1-r12}        SUB     r0, r0, #Angel_RegBlock_R0offset + (1*4)        LDR     r14, [r0, #Angel_RegBlock_R0offset + (14*4)]        LDR     r0, [r0, #Angel_RegBlock_CPSRoffset]        MSR     CPSR_f, r0    ; Only reinstate the flag values !        ; Set r0 to the address of Angel_ExitToUser        IMPORT  Angel_ExitToUSR        LDR     r0, =Angel_ExitToUSR                ; Restore sp and resume        LDMFD   sp, {sp, pc}        ; And now the application executes in SVC mode with its own stack        ; and interrupts disabled.                IF (:LNOT: :DEF: MINIMAL_ANGEL) :LOR: MINIMAL_ANGEL = 0          IF :LNOT: (:DEF: JTAG_ADP_SUPPORTED :LOR: :DEF: ICEMAN_LEVEL_3)        ApplDeviceSWI            LDR     r2, =angel_ApplDeviceHandler            B       DoIndirectCall          ENDIF        ENDIF                IF :DEF: LATE_STARTUP :LAND: LATE_STARTUP <> 0LateStartupSWI          LDR     r2, =angel_LateBootInit          B       DoIndirectCall        ENDIF        UnrecognisedSWI  IF :DEF: ICEMAN_LEVEL_3 :LOR: (:DEF: MINIMAL_ANGEL :LAND: MINIMAL_ANGEL<>0)        ; We cannot report an unrecognised SWI within ICEMan        B       UnrecognisedSWI   ELSE        LDR     r2, =ADP_Stopped_SoftwareInterrupt        B       CallSerialiseTask  ENDIF	AREA except_reg_save,DATA, READWRITESavedR10 DCD 0                END

⌨️ 快捷键说明

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