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

📄 crt1.s

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 S
📖 第 1 页 / 共 2 页
字号:
    .endif


do_initcopy:
    .ifndef NOINIT
	;
	; Call initcopy to do any copy/init of sections      
	;
	; First setup initial stack; initopy requires it
	;
	mov	r0,TOM_reg			; default top of memory
	mov	r1,1				; pre-initcopy
	bl	_stkinit
	bl	_initcopy
    .endif

initial_stack:
    .ifndef	NOSTACK
	;
	; Some systems may transfer control here without initially 
	; setting up a stack so we look for this here. We cannot even
	; trust sp to contain anything but garbage
	;
	; This may provide only a temporary SP with a bare minimum
	; of stack.
	; 
	;
	mov	r0,TOM_reg			; default top of memory
	mov	r1,0				; post-initcopy
	bl	_stkinit
    .endif



    ; full addressability now available


save_entry_stack:
	; SPA_reg is now either 0 or the incoming sp
	; Save it in .data for possible return
	la	r1,_mw_entry_stack
	str	SPA_reg,[r1]


check_for_hostlink:
	; turn of Angel swi's if hostlink available
	.weak	__HOSTLINK__
	la	r1,__HOSTLINK__
	cmp	r1,0
	beq	start_os
	la	r1,_use_swi
	cmp	r1,0
	mov	r0,0
	str	r0,[r1]


start_os:
    .ifndef NOSTARTK
	;
	; Call startup routine for RTOS kernel
	; This may or may not return
	; If this doesn't return then stack/heap allocation and control
	; as well as C++ intiialization must be performed by RTOS
	;
	bl	__start_kernel
    .endif



	
setup_memory:
    .ifndef NOMEM
	;
	; Call _mem_init to initialize memory vars for MetaWare heap/stack
	; Either set up custom stack or call this to use MetaWare defaults
	; When calling, r0 is boolean indicating whether to use 
	; heapinfo SWI call or not, set r0 to TRUE to use SWI call. 
	; If heapinfo is not supported, set r0 ot 0 to prevent SWI call.
	; Even if r0 is set, _mem_init may override if user vars are set
	; For source to _mem_init, see lib/src/c/misc_g/mem.s
	;
	; This call is done indirectly through .set variable 
	; "mem_init_function" which can be redefined or set to zero
	;
	; A default _mem_init is located in libmw.a; this can be overridden
	; by putting your own _mem_init into an RTOS-specific library or
	; by including it in the link command prior to libmw.a
	;
	la	r3,mem_init_function
	cmp	r3,0
	beq	no_mem_init
	mov	r0,UseHeapInfoSWI		; bool true if use heap swi
	mov	r1,TOM_reg				; default top of memory
	cmp	r1,0
	bne	have_top
	ldr	r1,=TopOfMemory			; hard value for top-of-mem
    have_top:
	ldr	r2,=DefaultStackSize		; default stack size
	bl	mem_init_function
    no_mem_init:
    .endif


call_program:
	;
	; Call the program
	; Check for call to C++ init and cpp_init, then call main
	;
	; NOTE: Usable stack must be set up by this point
	;
	; Stand-alone version calls low-level __cpp_initialize before
	; main and calls __cpp_finalize afterward; for ANSI compatability
	; non-standalone version call hi-level __cpp_init which will
	; register _fini with atexit() and then do cpp_init.
	;
	.extern	main
	.extern _mw_main
	.extern __cpp_initialize
	.extern __cpp_finalize
	.extern __cpp_init
    .ifdef STANDALONE
	; no C libraries
	.ifndef NOCPP
	bl	__cpp_initialize
	.endif
	mov	r0,0
	mov	r1,0
	bl	main			; call main
	.ifndef NOCPP
	bl	__cpp_finalize
	.endif
	b	_exit			; lo -level exit
    .else
	.ifndef NOCPP
	bl 	__cpp_init		;; call init & register fini w/ atexit
	.endif
	mov	r0,do_argv		; arg is 1 to get command-line
	bl	_mw_main		; call to init runtime & go to main
	.ifdef _DLL
		bl	_return		; return to os without cleanup
	.else
		bl	exit		; exit will call cpp_finalize 
	.endif
    .endif
	.ltorg

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Exit for _DLL & _THUMBRT programs -- they return to OS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    .if	$defined(_DLL) || $defined(_THUMBRT)
	.global	_return
	.type	_return,@function
	;
	; _return is called by _exit to return from the program if
	; it was called as a function. It can be called from anywhere.
	; It is assumed that entry sp was valid and that mw_entry_stack
	; was set up. Entry lr must have been valid too.
_return:
	; check for entry stack
	mov	r3,0
	mov	ip,r3
	la	r1,_mw_entry_stack
	ldr	r1,[r1]
	cmp	r1,0
	beq	do_return
	; reset stack to frame established on entry
	mov	sp,r1
	; reestablish non-volatile regs
	.if $thumb
		pop	{r4-r7}
		mov	r8,r4
		mov	r9,r5
		mov	r10,r6
		mov	r11,r7
		pop	{r4-r7}
		pop	{r3}
		mov	ip,r3
	.else
		ldmia	sp!,{r4-r11,ip}
	.endif
do_return:
	; return to OS
	; ip either has return lr; or it is zero
	.if $inter || $thumb 
	bx	ip
	.else
	mov	pc,ip
	.endif
    .endif
	.ltorg


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Basic Startup Procedure
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Unless control is passed to an alternate startup entry point, startup
; begins at symbol "_start".  From that point, a few initialization 
; processes must take place...
;
;	1) Memory initiailization (see below)
;	2) C++ initialization
;	3) Command-line (argv,argc) setup
;	4) Call main()
;
; The first of these is discussed in greater detail below. Essentially
; the startup process must initialize a stack and a heap. There are 
; various methods for setting up these. By default, function _mem_init
; is called to perform most of this setup.
;
; C++ initialization is required for the setup of initialized static 
; variables. These are initialized in two stages.  First, function _init
; is called to register constuctors.  Then either __cpp_init or __cpp_initialize
; is called.  The difference between these if that __cpp_init registers
; the C++ finalize routine with atexit(); the __cpp_initialize routine
; does not.  The _init routine is constructed in the .init section.  This
; is a special text section for only the one _init routine. There is also
; a .fini section for the _fini routine, which is called at the end by the
; __cpp_finalize routine. For any of this to work, you must have files,
; crti.o and crtn.o as part of your linker command line (they will be added
; automatically by the hcarm driver program if it is used for the linker
; command. Furthermore, crti.o must be the first object on the command, adn
; crtn.o must be the last.
;
; Command line processing is done by function _mw_main().  In fact that 
; is practically all _mw_main does except to call user-function main().
; An argument is passed to _mw_main to tell it whether to do command line
; processing or not. 
; 
; Finally, in _STANDALONE mode, you must call main() directly.
; 
; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; More on Memory Setup
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Variables for setting heap/stack layout (see lib/src/c/misc_g/mem.s)
;
; Also for default heap and stack helper functions see...
;	
;	lib/src/c/misc_g/stack.s
;	lib/src/c/misc_g/heap.s
;
; For specific OS initialization see specific startup files (e.g. threadx.s)
;
;
; There are vars that can be set within a program to overide standard settings.
; They must be initialized to the desired values. Dynamic assignment will
; have no effect.
;
; __heap_limit,__heap_base,__stack_limit,__stack_base take precedence
; over any other method of determining memory map. Only __heap_base is 
; checked.  If it is not defined, all of them are ignored; if it is defined
; all of them are read. However, if __heap_limit==__stack_limit, memory
; is assumed to be contiguous and both values are discarded.
;
; __root_stack_size is used to determine stack_limit if it is not known.
; It is also used when memory is contiguous to determine the initial size
; of the stack.
;
; __top_of_memory can be defined to overide the syscall to HEAPINFO.  If it
; is defined, memory is assumed to be contiguous between the top of the
; image and __top_of_memory; and memory will be layed out accordingly.
; Note:__heap_base will overide __top_of_memory.
;
; sp$$stack$$Base can be set by the linker as a mem addr to mov into SP.
; This only happens if all user-defined options are exhausted and the 
; stack and heap are contiguous.
;
; All of this stuff is set up in _mem_init (lib/src/c/misc_g/mem.s)
; and can be completely overriden by not calling _mem_init and not
; using stack/heap allocation or alloca.
;
; _mem_init(bool use_heap_swi, long dflt_top_of_mem, long dflt_stack_size)
;
; 	use_heap_swi:	True if heapinfo SWI is supported
; 	dflt_top_of_mem:Default to use for top of mem if can't be determined
;	dflt_stack_size:Default to use for stack size is can't be determined
;
; Prior to the call to _mem_init, a stack must be initialized. Some systems
; may have already done this prior to transferring control to _start; some
; may have no stack available on entry, so one must be initialized. For this
; purpose, we examine vars to determine if we must setup an initial stack.
; 
; __startup_stack_base, __startup_stack_limit if defined will be used to 
; initialize such a startup stack. However, if _initdat is on (which is now
; the default, there is no way to access them until after _initopy().
; 
;
; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PIC/PID and DLL support (position-independent, reentrant code)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 
; MetaWare provides PIC/PID (position independent code/data) either for
; standalone embedded programs that need the flexibility to be moved in
; flash or ram; or for DLL modules that need to be loaded at unknown 
; locations to be utilized by other programs. 
;
; NOTE: We do not yet support a DLL calling mechanism. 
;
; With the present scheme, control can only be transferred to a DLL via
; an outside agent (OS or load-supervisor). The outside agent must keep 
; track of r9 (sb) and stack values approprtiate for each invocation of 
; a DLL. MetaWare only provides the ability to create a PIC/PID object,
; and the mechanism here in crt1, which will allow a module to return
; to its caller rather than exit with a system halt or branch to zero.
; WHen crt1.s is assembled with -D_DLL the call to exit() will be avouded
; (unless called by the program), and _start will return after calling
; main().
;
; To start in PIC mode the crt1 uses a different sequence. Much of the 
; startup procedure is done in misc_g/_pic.s. Refer to hcdir/doc/pictable.txt
;
; To make a DLL, you can build this file (crt1.s) with -D_DLL and the 
; startup will set up an exit sequence that will return control to the 
; caller. For this to work, a valid sp must be passed into _start.

⌨️ 快捷键说明

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