📄 cstartup.s79
字号:
EXTERN __low_level_init
#ifdef _ECPLUSPLUS
EXTERN __call_ctors
#endif /* _ECPLUSPLUS */
EXTERN main
EXTERN exit
EXTERN _exit
; Execution starts here.
; After a reset, the mode is ARM, Supervisor, interrupts disabled.
LTORG
CODE32
?cstartup
; Initialize the stack pointers.
; The pattern below can be used for any of the exception stacks:
; FIQ, IRQ, SVC, ABT, UND, SYS.
; The USR mode uses the same stack as SYS.
; The stack segments must be defined in the linker command file,
; and be declared above.
mrs r0,cpsr ; Original PSR value
bic r0,r0,#MODE_BITS ; Clear the mode bits
orr r0,r0,#IRQ_MODE|NOINT ; Set IRQ mode bits
msr cpsr_c,r0 ; Change the mode
ldr sp,=SFE(IRQ_STACK) & 0xFFFFFFF8 ; End of IRQ_STACK
ORR r1,r0,#FIQ_MODE|NOINT
MSR cpsr_cxsf,r1 ;FIQMode
ldr sp,=SFE(FIQ_STACK) & 0xFFFFFFF8 ; End of FIQ_STACK
; Changed to the preferred mode
bic r0,r0,#MODE_BITS ; Clear the mode bits
orr r0,r0,#SVC_MODE ; Set Supervisor mode bits; enable IRQ/FIQ
msr cpsr_c,r0 ; Change the mode
ldr sp,=SFE(CSTACK) & 0xFFFFFFF8 ; End of CSTACK
; Change to the preferred intsruction set
#ifdef __THUMB_LIBRARY__
adr r0,?thumb_entry ; bit 0 is set on a Thumb code label
bx r0
CODE16
PUBLIC ?thumb_entry ; Symbol to make debuggers happy
?thumb_entry
#endif
; Initialize segments.
; __segment_init and __low_level_init are assumed to use the same
; instruction set and to be reachable by BL from the ICODE segment
; (it is safest to link them in segment ICODE).
bl __low_level_init
cmp r0,#0
beq after_segment_init
bl __segment_init
b after_segment_init
LTORG
after_segment_init:
REQUIRE ?jump_to_main
; Call the constructors of all global objects. This code will only
; be used if any EC++ modules defines global objects that need to
; have its constructor called before main.
#ifdef _ECPLUSPLUS
RSEG ICODE:CODE:NOROOT(2)
PUBLIC ?call_ctors
?call_ctors:
LDR R0,=SFB(DIFUNCT)
LDR R1,=SFE(DIFUNCT)
bl __call_ctors
b after_call_ctors
LTORG
after_call_ctors:
#endif /* _ECPLUSPLUS */
; Jump to main, using BX. Set _exit as the return address.
; main may be located anywhere in memory, and be of
; either ARM or Thumb mode, since BX is used.
; main is assumed to return using BX (__interwork) if it is of
; a different mode than cstartup, otherwise it will return
; in the wrong mode, causing unpredicatble behaviour.
require _exit
RSEG ICODE:CODE:NOROOT(2)
PUBLIC __main
?jump_to_main:
ldr r0,=?call_exit
mov lr,r0 ; Return address = _exit
ldr r0,=main
bx r0
__main:
?call_exit:
ldr r4,=_exit
mov lr,r4
ldr r4,=exit
bx r4
; It is not possible to fall through to _exit, because it is linked
; in a different segment.
LTORG
ENDMOD ?cstartup
;-------------------------------------------------------------dl-sanl0.r79--
; ?_EXIT
; main may return an exit code in R0, or _exit may be called with
; the exit code in R0.
; If the exit code is needed for som reason, R0 should be stored
; in e.g. one of the registers R4-R7, so that the value is
; preserved when calling __call_dtors and _Close_all.
;---------------------------------------------------------------
MODULE ?_EXIT
RSEG LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
PUBLIC _exit
; EXTERN ?jump_to_exit
REQUIRE ?jump_to_exit
CPU_MODE ; Either Thumb or ARM mode
_exit:
; Fall through to the next module
RSEG LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
; EXTERN ?exit_restore
; REQUIRE ?jump_to_exit
REQUIRE ?exit_restore
PUBLIC ?exit_save
?exit_save:
MOV R4, R0
; ENDMOD
;---------------------------------------------------------------
; ?CALL_DTORS
; This module is only linked if needed by atexit.
;---------------------------------------------------------------
; MODULE ?CALL_DTORS
RSEG LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
PUBLIC __cstart_call_dtors
; EXTERN ?exit_save
EXTERN __call_dtors
REQUIRE ?exit_save
; CPU_MODE ; Either Thumb or ARM mode
; This label is required by "__record_needed_destruction".
__cstart_call_dtors:
bl __call_dtors
; Fall through to the next module
; ENDMOD
;---------------------------------------------------------------
; ?CALL_CLOSE
; This module is only linked if needed for closing files.
;---------------------------------------------------------------
; MODULE ?CALL_CLOSE
RSEG LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
PUBLIC __cstart_closeall
EXTERN _Close_all
; EXTERN ?exit_save
REQUIRE ?exit_save
CPU_MODE ; Either Thumb or ARM mode
; This label is required by functions operating on files
__cstart_closeall:
bl _Close_all
; Fall through to the next module
; ENDMOD
;---------------------------------------------------------------
; ?_EXIT_END
; Restore the argument previously stored by the "save" section
; above.
;---------------------------------------------------------------
; MODULE ?_exit_end
RSEG LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
PUBLIC ?exit_restore
?exit_restore:
MOV R0, R4
;; Fall through to the __exit code below
; ENDMOD
;---------------------------------------------------------------
; ?JUMP_TO_EXIT
;---------------------------------------------------------------
; MODULE ?JUMP_TO_EXIT
RSEG LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
PUBLIC ?jump_to_exit
EXTERN __exit
CPU_MODE ; Either Thumb or ARM mode
; It is not possible to fall through to __exit, because the following
; module is only used when linking for debugging (XLINK -r).
?jump_to_exit:
bl __exit ; Thumb BL has longer reach than B
ENDMOD
;---------------------------------------------------------------
; ?__EXIT
; __exit is declared PUBWEAK, which makes XLINK skip this module
; if another module containing a PUBLIC __exit is linked.
;---------------------------------------------------------------
MODULE ?__EXIT
RSEG LIB_SEGMENT:CODE:NOROOT(2)
PUBWEAK __exit
CPU_MODE ; Either Thumb or ARM mode
__exit
#ifdef __THUMB_LIBRARY__
bx pc
nop
#endif
CODE32
b . ; Eternal loop
ENDMOD
;---------------------------------------------------------------
; ?INITTAB
; This module is only linked if needed by e.g. __segment_init.
; The INITTAB segment contains segment initialization entries.
; See segment_init.h.
;---------------------------------------------------------------
MODULE ?INITTAB
RSEG INITTAB:CONST(2) ; Declaration for SFB/SFE below
RSEG HUGE_C:CONST:NOROOT(2)
DATA
PUBLIC __segment_begin_INITTAB
PUBLIC __segment_end_INITTAB
__segment_begin_INITTAB DC32 SFB(INITTAB)
__segment_end_INITTAB DC32 SFE(INITTAB)
ENDMOD
MODULE ?ISRVECT
RSEG ISRVECT:DATA:NOROOT(2)
PUBLIC pISR_Reset, pISR_Undef, pISR_SWI, pISR_Pabort, pISR_Dabort
PUBLIC pISR_Reserved, pISR_IRQ, pISR_FIQ
PUBLIC pISR_EXT0, pISR_TIMER0, pISR_EXT2, pISR_U0TINT, pISR_U0RERR, pISR_U1TINT, pISR_U1RERR
DATA
pISR_Reset DC32 0
pISR_Undef DC32 0
pISR_SWI DC32 0
pISR_Pabort DC32 0
pISR_Dabort DC32 0
pISR_Reserved DC32 0
pISR_IRQ DC32 0
pISR_FIQ DC32 0
;Don't use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
pISR_EXT0 DC32 0
pISR_EXT1 DC32 0
pISR_EXT2 DC32 0
pISR_EXT3 DC32 0
pISR_U0TINT DC32 0
pISR_U0RERR DC32 0
pISR_U1TINT DC32 0
pISR_U1RERR DC32 0
pISR_GDMA0 DC32 0
pISR_GDMA1 DC32 0
pISR_TIMER0 DC32 0
pISR_TIMER1 DC32 0
pISR_HDLCTXA DC32 0
pISR_HDLCRXA DC32 0
pISR_HDLCTXB DC32 0
pISR_HDLCRXB DC32 0
pISR_ECBDMATx DC32 0
pISR_ECBDMARx DC32 0
pISR_ECMACTx DC32 0
pISR_ECMACRx DC32 0
pISR_i2cbus DC32 0
ENDMOD
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -