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

📄 crt.s

📁 UCSO在三星S3C44B0X CPU上的移植。ejoy it
💻 S
📖 第 1 页 / 共 2 页
字号:
; NOTE: not such luxury with uC/OS (yet).;        ADR     a1, RTErrorHead;        SWI     Write0                ; write preamble...;        ADD     a1, v1, #4;        SWI     Write0                ; write error diagnosis;        ADR     a1, RTErrorTail;        SWI     Write0                ; write postlude;        MOV     a1, #255        B       |__rt_exit|           ; and terminate with non-zero exit codeerr_handler        DCD     |__err_handler|save_regs_and_trap        STMFD   sp!, {sp, lr, pc}        STMFD   sp!, {r0-r12}        STR     lr, [sp, #4*15]       ; caller's pc is my lr        MOV     a2, sp        MOV     a1, ip        B       |__rt_trap|RTErrorHead        DCB     10, 13, "run time error: ", 0RTErrorTail        DCB     10, 13, "program terminated", 10, 13, 10, 13, 0        ALIGN;----------------------------------------------------------------------------;; YOU SHOULDN'T NEED TO ALTER ANY OF THE FOLLOWING IN A FIRST RETARGETTING.  ;;----------------------------------------------------------------------------;;----------------------------------------------------------------------------;        AREA    |C$$code$$__rt_alloc|, CODE, READONLY; The code area containing __rt_alloc                                        ;;----------------------------------------------------------------------------;; Primitive support for heap memory management.                              ;;                                                                            ;; NOTES                                                                      ;;                                                                            ;; 1/ The allocator embeds knowledge of the memory layout and interacts with  ;;    the stack limit checking code. Here we assume a single address space    ;;    with the stack at the top growing down and the heap below it growing    ;;    up, with a gap (free memory) in between.                                ;;                                                                            ;; 2/ Failure of the stack-limit check is fatal. However, failure of the low- ;;    level heap allocator is passed back to its caller.                      ;;----------------------------------------------------------------------------;|__rt_alloc|                             ; alloc;; unsigned __rt_alloc(unsigned minwords, void **block);;; This tries to allocate a block of sensible size >= minwords. Failing that,; it allocates the largest possible block of sensible size. If it can't do; that, it returns zero. *block is set to point to the start of the allocated; block (NULL if none has been allocated).;; NOTE: works in units of WORDS, NOT bytes.;; In this implementation, sl - StackSlop marks the end of allocatable store.        CMP     a1, #MinHeapIncrement    ; round up to at least        MOVLT   a1, #MinHeapIncrement    ; MinHeapIncrement words...        LDR     a3, HeapLimitAdr        LDR     a4, [a3]                 ; current heap high-water mark        SUB     ip, sl, #StackSlop       ; current stack low-water mark        CMP     a4, ip        MOVGE   a4, #0                   ; no space, *block = NULL        STR     a4, [a2]        MOVGE   a1, #0                   ; no space, return 0        ADD     a4, a4, a1, LSL #2       ; proposed new heap limit        CMP     a4, ip        SUBGT   a2, a4, ip               ; byte overlap, >= 0 by earlier code        SUBGT   a1, a1, a2, LSR #2       ; reduce word request        MOVGT   a4, ip                   ; new high-water = stack low-water        STR     a4, [a3]          RET     HeapLimitAdr        DCD     HeapLimit;----------------------------------------------------------------------------;        AREA    |C$$code$$__rt_stkovf|, CODE, READONLY; The code area containing __rt_stkovf_*                                     ;;----------------------------------------------------------------------------;; C stack-limit checking support.                                            ;;                                                                            ;; NOTES                                                                      ;;                                                                            ;; 1/ Stack-limit-checking is optional - you can compile your C code without  ;;    stack-limit checks (#pragma nocheck_stack or cc -zps0). However, the    ;;    cost of the check is (very) small and the value sometimes considerable. ;;                                                                            ;; 2/ The limit check embeds knowledge of the memory layout and interacts     ;;    with the primitive memory management supported by __rt_alloc. Here, we  ;;    assume a single address space with the stack at the top growing down    ;;    and the heap below it growing up, with a gap (free memory) in between.  ;;                                                                            ;; 3/ Failure of the stack-limit check is fatal. However, failure of the low- ;;    level heap allocator is passed back to its caller.                      ;;                                                                            ;; 4/ This implementation never reduces the size of the stack. It simply      ;;    moves the low-water mark monatonically downwards. It is easy to do      ;;    better, but, of course, it takes more code and is more target-specific. ;;----------------------------------------------------------------------------;|__rt_stkovf_split_small|                         ; stkovf_split_small_frame ;;; Enter here when a C function with frame size <= 256 bytes underflows; the stack low-water mark + StackSlop (sl). The stack space required has; already been claimed by decrementing sp, so we set the proposed sp (ip); to the actual sp and fall into the big-frame case.        MOV     ip, sp       ; fall into big-frame case with size of 0.|__rt_stkovf_split_big|                             ; stkovf_split_big_frame ;;; Enter here when a C function with frame size > 256 bytes would underflow; the stack low-water mark + StackSlop (sl). No stack space has been claimed; but the proposed new stack pointer is in ip.        SUB     ip, sp, ip                      ; frame size required...        CMP     ip, #DefaultStackIncrement      ; rounded up to at least        MOVLT   ip, #DefaultStackIncrement      ; the default increment        SUB     sl, sl, ip        SUB     sl, sl, #StackSlop              ; new stack low-water mark        LDR     ip, HeapLimitAdr                ; check doesn't collide with        LDR     ip, [ip]                        ; the heap.        CMP     ip, sl        ADD     sl, sl, #StackSlop              ; restore safety margin        BGT     stackoverflow        RET                                     ; and return if OK...stackoverflow        ADR     ip, StackOverflowError        B       save_regs_and_trapStackOverflowError        DCD     3        DCB     "stack overflow", 0        ALIGN;----------------------------------------------------------------------------;        AREA    |C$$code$$__divide|, CODE, READONLY; The code area containing __rt_sdiv, __rt_udiv, __rt_sdiv_10, __rt_udiv10   ;;----------------------------------------------------------------------------;; GENERIC ARM FUNCTIONS - divide and remainder.                              ;;                                                                            ;; NOTES                                                                      ;;                                                                            ;; 1/ You may wish to make these functions part of your O/S kernel, replacing ;;    the implementations here by branches to the relevant entry addresses.   ;;                                                                            ;; 2/ Each divide function is a div-rem function, returning the quotient in   ;;    r0 and the remainder in r1. Thus (r0, r1) -> (r0/r1, r0%r1). This is    ;;    understood by the C compiler.                                           ;;                                                                            ;; 3/ Because of its importance in many applications, divide by 10 is treated ;;    as a special case. The C compiler recognises divide by 10 and generates ;;    calls to __rt_{u,s}div10, as appropriate.                               ;;                                                                            ;; 4/ Each of the implementations below has been coded with smallness as a    ;;    higher priority than speed.  Unrolling the loops will allow faster      ;;    execution, but will produce much larger code.  If the speed of divides  ;;    is critical then unrolled versions can be extracted from the ARM ANSI C ;;    Library.                                                                ;;                                                                            ;;----------------------------------------------------------------------------;; div_core is used by __rt_sdiv and __rt_udiv, and corrupts a3, a4 and ipdiv_core        CMP     a3, a4        MOVHI   a4, a4, ASL #1        BHI     div_corediv_core2        CMP     a2, a4        ADC     ip, ip, ip        SUBHS   a2, a2, a4        CMP     a1, a4        MOVLO   a4, a4, LSR #1        BLO     div_core2        MOV     a1, ip        RET; Signed divide of a2 by a1: returns quotient in a1, remainder in a2; Quotient is truncated (rounded towards zero).; Sign of remainder = sign of dividend.; Destroys a3, a4 and ip; Negates dividend and divisor, then does an unsigned divide; signs; get sorted out again at the end.|__rt_sdiv|        MOVS    a3, a1        BEQ     dividebyzero            ; ip now unwanted        RSBMI   a1, a1, #0              ; absolute value of divisor        EOR     a3, a3, a2        ANDS    ip, a2, #&80000000        ORR     a3, ip, a3, LSR #1        STMFD   sp!,{a3,lr}        ; saved a3:        ;  bit 31  sign of dividend (= sign of remainder)        ;  bit 30  sign of dividend EOR sign of divisor (= sign of quotient)        RSBNE   a2, a2, #0              ; absolute value of dividend        MOV     a3, a2        MOV     a4, a1        MOV     ip, #0        BL      div_core        LDMFD   sp!,{a3}        MOVS    a3, a3, ASL #1        RSBMI   a1, a1, #0        RSBCS   a2, a2, #0    IF {CONFIG} = 26        LDMFD   sp!,{pc}^    ELSE        LDMFD   sp!,{pc}    ENDIF; Unsigned divide of a2 by a1: returns quotient in a1, remainder in a2; Destroys a4, ip and r5|__rt_udiv|        MOVS    a4, a1        BEQ     dividebyzero        MOV     ip, #0        MOV     a3, #&80000000        CMP     a2, a3        MOVLO   a3, a2        B       div_core;; Fast unsigned divide by 10: dividend in a1, divisor in a2.; Returns quotient in a1, remainder in a2.; Also destroys a3.;; Calculate x / 10 as (x * 2**32/10) / 2**32.; That is, we calculate the most significant word of the double-length; product. In fact, we calculate an approximation which may be 1 off; because we've ignored a carry from the least significant word we didn't; calculate. We correct for this by insisting that the remainder < 10; and by incrementing the quotient if it isn't.|__rt_udiv10|                                                       ; udiv10 ;        MOV     a2, a1        MOV     a1, a1, LSR #1        ADD     a1, a1, a1, LSR #1        ADD     a1, a1, a1, LSR #4        ADD     a1, a1, a1, LSR #8        ADD     a1, a1, a1, LSR #16        MOV     a1, a1, LSR #3        ADD     a3, a1, a1, ASL #2        SUB     a2, a2, a3, ASL #1        CMP     a2, #10        ADDGE   a1, a1, #1        SUBGE   a2, a2, #10        RET;; Fast signed divide by 10: dividend in a1, divisor in a2.; Returns quotient in a1, remainder in a2.; Also destroys a3 and a4.; Quotient is truncated (rounded towards zero).; Make use of __rt_udiv10|__rt_sdiv10|                                                       ; sdiv10 ;        MOV     ip, lr        MOVS    a4, a1        RSBMI   a1, a1, #0        BL      __rt_udiv10        CMP     a4, #0        RSBMI   a1, a1, #0        RSBMI   a2, a2, #0    IF {CONFIG} = 26        MOVS    pc, ip    ELSE        MOV     pc, ip    ENDIF;; Test for division by zero (used when division is voided).|__rt_divtest|                                                     ; divtest ;        CMPS    a1, #0        RET     NEdividebyzero        ADR     ip, DivideByZeroError        B       save_regs_and_trapDivideByZeroError        DCD     1        DCB     "divide by 0", 0        ALIGN        END

⌨️ 快捷键说明

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