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

📄 suppasm.s

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 S
📖 第 1 页 / 共 4 页
字号:
        SUBS    a1, lr, a4        LDRNE   pc, [sp], #4        CMP     lr, #0        CMPNE   a4, #0        SUBNES  a3, a3, #1        BNE     %0        LDR     pc, [sp], #4        EXPORT  __rt_strcpy__rt_strcpy     ROUT        MOV     ip, a10       LDRB    a3, [a2], #1        STRB    a3, [ip], #1        CMP     a3, #0        BNE     %0        MOV     pc, lr        EXPORT  __rt_strcat__rt_strcat     ROUT        MOV     ip, a1          ; so we can return a10        LDRB    a3, [ip], #1        CMP     a3, #0        BNE     %0        SUB     ip, ip, #1      ; want to overwrite NUL        1       LDRB    a3, [a2], #1        STRB    a3, [ip], #1        CMP     a3, #0        BNE     %1                MOV     pc, lr  IF :DEF: LINKING_WITH_CLIB        ; stack checking support is in the C lib  ELSE        ; ---------------------------------------------------------------------        ; -- Software stack checking support ----------------------------------        ; ---------------------------------------------------------------------        ; The following functions are provided for software stack        ; checking. If hardware stack-checking is being used then the        ; code can be compiled without the PCS entry checks, and        ; simply rely on VM management to extend the stack for a        ; thread.        ;        ; The stack extension event occurs when the PCS function        ; entry code would result in a stack-pointer beneath the        ; stack-limit register value. The system relies on the        ; following map:        ;        ; +-----------------------------------+ <-- end of stack block        ; | ...                               |        ; | ...                               |        ; | active stack                      |        ; | ...                               | <-- sp (stack-pointer) somewhere in here        ; | ...                               |        ; +-----------------------------------+ <-- sl (stack-limit)        ; | stack-extension handler workspace |        ; +-----------------------------------+ <-- base of stack block        ;        ; The "stack-extension handler workspace" is an amount of        ; memory in which the stack overflow support code must        ; execute. It must be large enough to deal with the worst        ; case through the stack overflow handler code.        ;        ; At the moment the compiler expects this to be AT LEAST        ; 256bytes. It uses this fact to code functions with small        ; local data usage within the overflow space.        ;        ; NOTE: We may need to increase the space between sl and the        ; true limit to allow for the stack extension code and any        ; other system software that may temporarily use the stack of        ; the current foreground thread.        ;        ; The following example stack overflow handling code requires        ; the following run-time functions:        ;       __rt_allocmem   ; Kernel memory allocator "malloc"        ;       __rt_freemem    ; Kernel memory allocator "free"        ; We need to ensure that the MAXIMUM stack usage possible by the        ; above routines, fits into the stack overflow handler space        ; left beneath the "sl" value. The above routines also need to        ; be compiled with stack-overflow checking disabled.        ;        ; If the "__rt_" routines needed by this code are not        ; interrupt safe (i.e. if they cannot be called from within an        ; interrupt handler) then this code must ensure that any code        ; executing as part of an interrupt handler does NOT generate        ; a stack extension event.        AREA    |StackOverflow$$Code|,CODE,READONLY        KEEP        ; NOTE: This code assumes that it is entered with a valid        ; frame-pointer. If the system is being constructed without        ; frame-pointer support, then the following code will not        ; work, and an alternative means of providing soft        ; stack-extension will need to be coded.        EXPORT __rt_stkovf_split_small__rt_stkovf_split_small        ; Called when we have a standard register saving only        ; stack-limit check failure.        MOV     ip,sp   ; ensure we can calculate the amount of stack required        ; and then fall through to...        IMPORT Angel_StackBase        EXPORT __rt_stkovf_split_big__rt_stkovf_split_big        ; If we are in a privileged mode then stack overflow is fatal, so        ; we should do nothing more than output a debugging message and        ; give up!        MRS     r0, CPSR        AND     r0, r0, #ModeMask        CMP     r0, #USRmode        BEQ     USRmodeStackCheck        MOV     r1, r0        ADR     r0, PrivilegedStackOverflowMessage ;  r0 == a1        B       __rt_asm_fatalerror        PrivilegedStackOverflowMessage        DCB     "Stack Overflow in mode %2X\n"        ALIGNUSRmodeStackCheck        ; If this is the AngelStack then sl should        ; be somewhere within the Angel Stack range        LDR     r1, =Angel_StackBase        LDR     r1, [r1]        ADD     r0, r1, #Angel_AngelStackLimitOffset        ADD     r1, r1, #Angel_AngelStackOffset        SUB     r1, r1, #1        CMP     sl, r0        CMPHS   r1, slAngelStackOverflow        BHS     AngelStackOverflowRealStackCheckCode        ; Called when we have a large local stack allocation (>        ; 256bytes with the current C compiler) which would cause an        ; overflow. This version is called when the compiler generated        ; PCS code has checked its requirement against the stack-limit        ; register.        ;        ; in:   sp = current stack-pointer (beneath stack-limit)        ;       sl = current stack-limit        ;       ip = low stack point we require for the current function        ;       lr = return address back to the function requiring more stack        ;       fp = frame-pointer        ;        ;               original sp --> +----------------------------------+        ;                               | pc (12 ahead of PCS entry store) |        ;               current fp ---> +----------------------------------+        ;                               | lr (on entry) pc (on exit)       |        ;                               +----------------------------------+        ;                               | sp ("original sp" on entry)      |        ;                               +----------------------------------+        ;                               | fp (on entry to function)        |        ;                               +----------------------------------+        ;                               |                                  |        ;                               | ..argument and work registers..  |        ;                               |                                  |        ;               current sp ---> +----------------------------------+        ;        ; The "current sl" is somewhere between "original sp" and        ; "current sp" but above "true sl". The "current sl" should be        ; "APCS_STACKGUARD" bytes above the "true sl". The value        ; "APCS_STACKGUARD" should be large enough to deal with the        ; worst case function entry stacking (160bytes) plus the stack        ; overflow handler stacking requirements, plus the stack        ; required for the memory allocation routines, and the        ; exception handling code.        ;        ; THINGS TO NOTE:        ; We should ensure that every function that calls        ; "__rt_stkovf_split_small" or "__rt_stkovf_split_big" does so        ; with a valid PCS. ie. they should use "fp" to de-stack on        ; exit (see notes above).        ;        ; Code should never poke values beneath sp. The sp register        ; should always be "dropped" first to cover the data. This        ; protects the data against any events that may try and use        ; the stack. This is a requirement of APCS-3.        ;        SUB     ip,sp,ip        ; extra stack required for the function        STMFD   sp!,{v1,v2,lr}  ; temporary work registers        ;        ; For simplicity never attempt to extend the stack just report        ; an overflow.RaiseStackOverflow        ; in:  v1 = undefined        ;      v2 = undefined        ;      sl = stack-limit        ;      ip = amount of stack required        ;      sp = FD stack containing {v1,v2,lr}        ;      lr = undefined        ;        ;; 960506 KWelton               ;;              ;; I'm not sure what this is trying to do, but it all seems redundant        ;; to me - what we *really* want to do is report the overflow, and        ;; then stop in a tight loop.                ;; others disagree... this kills Angel, and without angel debug        ;; code, this is not useful. IJ has requested that such errors        ;; cause a restart of angel (i.e. jump to __rt_angel_restart)        ;; while debug builds can jump to Deadloop. -- 22/10/97 RIC                IF {FALSE}        MRS     v1,CPSR         ; get current PSR        TST     v1,#ModeMaskUFIS        MOV     v2, a1        LDR     a1, =angel_SWIreason_EnterSVC        DCD     angel_SWI_ARM        MOV     a1, v2        ; We are now in a suitably priviledged mode.        MSR     SPSR,v1         ; get original PSR into SPSR        STMFD   sp!,{r10-r12}   ; work registers        LDR     r10,=ADP_Stopped_RunTimeError        MOV     r11,#ADP_RunTime_Error_StackOverflow        MOV     lr,pc           ; return address        ELSE        MOV     a1, #angel_SWIreason_ReportException        LDR     a2, =ADP_Stopped_StackOverflow        DCD     angel_SWI_ARM        ENDIF                ;; If we get here, print a message and die...        ADR     a1, stkovfmsg        B       __rt_asm_fatalerrorstkovfmsg        DCB     "Stack Overflow\n"        ALIGN                ;; This instruction matched a STM above, but I can't see any way        ;;  of actualy executing it!! It should probably be removed. -- ric        LDMFD   sp!,{v1,v2,pc}  ; and return to caller  ENDIF ; :DEF: LINKING_WITH_CLIB        ; ---------------------------------------------------------------------        IF CACHE_SUPPORTED <> 0          ; Added for EBSARM, Instruction barrier range function. r0          ; contains start of range, r1 end.Cache_IBR          ; Simply call the board dependent macro          CACHE_IBR r0,r1,r2,r3          ; And return          MOV   pc,lr        ENDIF        IMPORT  Angel_EnterSVC        EXPORT  __rt_uninterruptable_loop__rt_uninterruptable_loop        MRS     a1, CPSR        AND     a2, a1, #ModeMask        CMP     a2, #USRmode        BLEQ    Angel_EnterSVC        ORRNE   a1, a1, #IRQDisable + FIQDisable        MSRNE   CPSR_cxsf, a1DeadLoop        B       DeadLoop        ; This code simulates the LogFatalError macro used in the C parts of        ; Angel. Enter it with a1 pointing at the error message.        EXPORT  __rt_asm_fatalerror        IMPORT  __rt_logerror, WEAK        IMPORT  __rt_logmsginfo, WEAK__rt_asm_fatalerror        ;; if the logerror routine exists, use it to print the message        LDR     a2, =__rt_logerror        CMP     a2, #0        BEQ     no_logerror                ;; these variables are used in C code to say where the call came from;        ;;  we don't have that info to hand for asm.        STMFD   sp!, {r1,r2,r3}        MOV     r1, #0        MOV     r2, #0        MOV     r3, #0        BL      __rt_logmsginfo        LDMFD   sp!, {r1,r2,r3}        BL      __rt_logerrorno_logerror        ; debug build jumps into DeadLoop, release build restarts Angel.        IF      DEBUG = 1        BL      __rt_uninterruptable_loop        ELSE        BL      __rt_angel_restart        ENDIF        ;; This routine exists as the action used when Angel needs to be        ;; restarted. There are two occasions; when the debugger asks for        ;; it, and when Angel detects a fatal error. The routine should        ;; reload Angel from ROM, if possible, and restart as if a        ;; power-on-reset had just occurred, as NOTHING can be assumed about        ;; the current state of anything in RAM.        ;;         ;; THIS ROUTINE NEVER RETURNS!        __rt_angel_restart        IMPORT __rom        EXPORT __rt_angel_restart        ;; for the moment, just start at the beginning again...        B __rom            ;; This is the interrupt system initialisation routine added    ;; to allow it to be called at will as a function.Init_Interrupt    EXPORT Init_Interrupt   IF :DEF: AT91_AIC_IRQ     IF AT91_AIC_IRQ <> 0      GET   aic.inc    ;INITAIC r0,r1,r2,r3     ENDIF     ENDIF    mov pc,lr   IF :DEF: AT91_AIC_IRQ     IF AT91_AIC_IRQ <> 0Get_Mode    EXPORT Get_Mode    MRS r0, CPSR    MOV pc, lr         ENDIF     ENDIF   IF :DEF: AT91_AIC_IRQ     IF AT91_AIC_IRQ = 2    EXPORT Interrupt_veneerInterrupt_veneer    SUB lr, lr, #4  ; Return from int address    STMFD   sp!, {r0-r3,lr}        ; Silicon bug fix - return if IRQ is taken whilst disabled    MRS r0, SPSR    ANDS    r14, r0, #0x80  ; I_BIT    LDMNEFD sp!,{r0-r3, pc}^        ; Now find out where the interrupt is called from (AIC vector)    LDR r3, =INT_IVR    LDR r3, [r3]    ; Now call the Interrupt Handler    MOV lr, pc    MOV pc, r3      ; To handler    ;; Should return here    LDMFD sp!, {r0-r3, pc}^                          ENDIF     ENDIF        END     ; EOF suppasm.s

⌨️ 快捷键说明

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