📄 crt1.s
字号:
.file "crt1.s"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;; Metaware crt1.s for Angel
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; NOTE: crt1 can now be assembled in thumb mode. This is for OS's that
; expect all application to be in Thumb mode at startup. To force
; thumb define -D_THUMBRT
;
; The following -Ddefines can be used when reassembling....
;
; -DSTANDALONE To build for stand-alone use (no C/C++ libraries)
; -DNOSWI To build with no swi calls use -DNOSWI
; -DNOHEAP To build with no heapinfo swi use -DNOHEAP
; -DNOSTACK To build with no stack (assume sp set on entry or by PIC)
; -DNOZERO To prevent zero-init of BSS (assumes done already by loader)
; -DNOMEM To avoid all mem init (nostack,noheap) -DNOMEM
; -DNOCMD To avoid commandline analysys (argv,argc)
; -DNOARGV To avoid commandline analysys (argv,argc)
; -DNOCPP To avoid C++ initiailization -DNOCPP
; -DNOSTARTK To avoid RTOS kernel initialize
; -DNOINIT To avoid calling initcopy
; -DNOPIC To avoid calling pictable init
; -D_PIC To provide for position-indepent startup
; -D_THUMBRT Force assembly in thumb mode for OS that expects thumb startup
; -D_DLL For DLL entry, establish stack and return on exit
; Define non-volatile regs used by _start
; Must be thumb regs for _THUMBRT (thumb startup) to work
;
; SPA_reg = reg to save incoming sp
; TOM_reg = reg to records top-of-memory
;
.define SPA_reg,r7
.define TOM_reg,r6
; macro to load an address
; Thumb mode wont accept cc arg
.macro la,reg,name,cc
.if $thumb
.if $defined(_PIC_REL)
ldr reg,=(name)@sdadisp
add reg,(name)@sdareg
.elseif $defined(_PIC) || $defined(_REENT)
mov reg,name@sdahi
lsl reg,reg,7
add reg,sb
ldr reg,[reg,name@sdalo]
.else
ldr reg,=name
.endif
.else
.if $defined(_PIC) || $defined(_REENT)
ldr\&cc reg,[sb,name@sda]
.else
ldr\&cc reg,=name
.endif
.endif
.endm
.ifdef NOSWI
.define NOHEAP,1
.endif
.ifdef NOARGV
.define NOCMD,1
.endif
.ifdef NOMEM
; For RTOS support, you should substitute an RTOS-specific
; mem init routine.
.define _NO_MEM_INIT,1
.endif
;
; Set global var to indicate whether swis can be used by runtime
; Default is Angel so set _use_swi to 1 unless standalone or noswi
;
; If linking with -Hhostlink to link in MetaWare hostlink, _use_swi
; will be turned off by hostlink's _mw_main. (see hl/hl_g/_mw_main.c)
;
; The default _mem_init will look at both _use_swi and
; __use_mw_hostlink (set in hostlink's _mw_main) to determine
; whether to use SWI for heap info. (see c/misc_g/mem.s)
;
.global _use_swi
.data
_use_swi:
.long 0 ;;;;; !$defined(NOSWI) && !$defined(STANDALONE)
.previous
;; determine whether to do argv commandline processing
do_argv = !$defined(NOCMD)
; NOTE: _trap,_exit,_div0 have been moved to misc_g/{_trap.s,_exit.s,_div0.s
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; basic default memory constants
;
;
TopOfMemory = 0x80000
DefaultStackSize = 16*1024
DefaultHeapSize = 16*1024
; define memory initialization function
.ifdef _NO_MEM_INIT
.set mem_init_function,0
.else
.set mem_init_function,_mem_init
.endif
.set UseHeapInfoSWI,!$defined(NOHEAP)
; variable to indicate zeroing of BSS
; simulators can set this variable to zero to prevent BSS zeroing
;
; variable to indicate wheter to use Angel's heap-info call
;
.rodata
__INITBSS__::
.long 1
.previous
.data
__UseHeapInfoSWI::
.long UseHeapInfoSWI
.previous
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Startup -- angel version
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.ifdef _THUMBRT
.option code16
.else
.option code32
.endif
.text
.global _start
.type _start,@function
.ifndef _THUMBRT
.align 16
.endif
.weak _0 ; dummy symbol to allow relative addr
.weak sp$$stack$$Base
_start:
ldr r2,=(sp$$stack$$Base-_0); use linker var if present
cmp r2,0
beq no_sp
mov sp,r2 ; setup initial sp
no_sp:
.if $defined(_DLL) || $defined(_THUMBRT)
; Check for sp. If non-zero, save lr for return to os
; Prgrams that start in thumb mode must return since interrupts
; and swi's are unavailable.
;
; If sp is non-zero save non-volatile regs and lr for return
mov r3,0
cmp sp,r3
beq no_push
; push regs
.if $thumb
push {r4-r7,lr}
mov r4,r8
mov r5,r9
mov r6,r10
mov r7,r11
push {r4-r7}
.else
stmdb sp!,{r4-r11,lr}
.endif
no_push:
mov SPA_reg,sp ; ind stack return by saving sp
.else
mov SPA_reg,0
.endif
do_pic:
.ifndef NOPIC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Check for _PIC (position-independent startup)
;
; We check for presence of the .picatble section. If it exists
; then we call _init_pic().
;
; This assumes loader has passed in data-section parameters
;
; sb(r9) data base -- start of space for R/W data or 0
; sp(r13) data top -- top of data or useable stack or 0
;
; If sp is 0, DefaultStackSize/DefaultHeapSize will be used to
; determine it, unless nothing is moved in which case _init_pic
; will check __MEMSIZE__ to see if the SeeCode debugger set the
; top of memory.
;
; Note: runtime assumes contiguous memory between sb && sp and will
; use memory above data & bss for heap and stack.
; If this memory is non-contiguous, heap-overlflow checking
; will not work unless you provide an alternate heap section
; or heap base/limit varibales (see mem.s).
;
; On return from _init_pic(), data will be
; relocated appropriately, and heap will be set to top of data
;
; sp -----> hi
; stack
; unused
; heaptop->
; heap area
; heap --->
; data & bss
; sb -----> lo
;
;
; Turn off initcopy,zerobss and stack calculation
; they will be performed by _init_pic
;
.weak _epictable ; use end of seg in case based at 0
ldr r0,=(_epictable-_0)
cmp r0,0 ; test for pictable seg
beq no_pic ; skip if no pictable
ldr r0,=(DefaultStackSize+DefaultHeapSize)
bl _init_pic ; see misc_g/_pic.s
la r1,_mw_top_estimate ; save sp for default top of mem
mov r2,sp
str r2,[r1]
la r1,__UseHeapInfoSWI ; turn off heap-info call
mov r0,0
str r0,[r1]
mov r1,sb ; check sb vectors and setup default
ldr r0,[r1]
cmp r0,0
bne save_entry_stack
str r1,[r1]
b save_entry_stack ; skip initcop,zerobss,and stack init
no_pic:
.endif
set_sb_reg:
;
; Initialize SB reg
;
.weak sb$$interLUdata$$Base
ldr r0,=(sb$$interLUdata$$Base-_0)
.ifdef _THUMBRT
mov sb,r0
.else
movs sb,r0
beq estimate_top
ldr r1,[r0]
cmp r1,0
streq r0,[r0] ; setup dummy dlltable
.endif
estimate_top:
;
; Check for top of memory, debuggers/loaders can poke
; __MEMSIZE__ to tell us where the top is.
; Save it in top_estimate variable for _mem_init
; Actual var must be in R/O mem or won't work with initcopy
;
ldr TOM_reg,=(__MEMSIZE__-_0) ; save in TOM_reg for later
ldr TOM_reg,[TOM_reg]
zerobss:
.ifndef NOZERO
;
; Call zero_init to initialize bss memory.
; If this is done by loader, comment out this call
; _zerobss has been moved to misc_g/_zerobss.s
; _zerobss requires no stack to run, and may be used to
; zero out bss even if the stack resides in bss.
; If cmd-file has been used to split up bss, this will not work
;
; UPDATE: We now check for _initdat. If _initdat is present, then
; we assume initcopy() will zerobss. This is now the default for
; the linker (-Bzerobss). To turn off zerobss via the linker, use
; linker option (-Bnozerobss). initcopy() does a much more thorough
; job and works even if bss sections have been split up. The
; special bss section, .stack, will not be zeroed.
;
.weak _einitdat
ldr r0,=(_einitdat-_0)
cmp r0,0
bne no_zero
ldr r0,=(__INITBSS__-_0)
ldr r0,[r0]
cmp r0,0
beq no_zero
bl _zerobss
no_zero:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -