SITE HOME
This web page explains the 'startup.s' file:
'startup.s' file is a assembly file used in almost all embedded C
projects with the Keil uVision IDE.
This is where the user will define mandatory things, without which
any C program which the user writes wont compile.
Here is an example of bare-minimum startup.s file that is necessary
to start writing any c-code.
It must
1. Declare a Stack Pointer
2. Declare a Reset_Handler routine.
3. Define minimum 'Vectors'
The ARM cortex M processors starts its execution from memory
location 0x0000_0000. It is certainly the case with Cortex-M3 and
Cortex-M4.
However the 32 bit values stored at the location 0x0000_0000 and at
0x0000_0004 have a bit of special meaning.
The value stored at 0x0000_0000 is treated as the value to which the
stack pointer will be initialized to
The value stored at 0x0000_0004 is treated as a jump location, where
the processor will jump to after initializing its stack pointer.
At this jump location the user is expected to write their
'Reset_Handler' code. It can be very simple as shown in the
following code.
1
Stack_Size EQU 0x00000400
2
AREA STACK,NOINIT,READWRITE,ALIGN=3
3 __stack_limit
4 Stack_Mem SPACE
Stack_Size
5 __initial_sp
6
7 ; Vector Table Mapped to Address 0 at Reset
8 AREA RESET, DATA, READONLY
9 EXPORT __Vectors
10 EXPORT __Vectors_End
11 EXPORT __Vectors_Size
12 __Vectors DCD __initial_sp ; Top of Stack
13
DCD Reset_Handler ; Reset Handler
14
15 __Vectors_End
16
17 __Vectors_Size EQU __Vectors_End - __Vectors
18
AREA |.text|, CODE, READONLY
19 Reset_Handler PROC
20
EXPORT Reset_Handler [Weak]
21
IMPORT __main
22
LDR R0, =__main
23
BX R0
24
ENDP
25
EXPORT __stack_limit
26
EXPORT __initial_sp
27
28
END
The line number 1. the user is declaring size of the stack. The word
'Stack_Size' is a key word, and 'EQU' is a assembler directive. EQU
directive gives a symbolic name to a numeric constant. This line
effectively describes the label 'Stack_Size' having a numeric value
of 0x400.
What exactly 'Stack_Size' is, is still a mystery. It is being
referred to as a 'Key Word' here. But it may be a 'Macro', or it may
just be a pre-defined symbol or a label which is already know to the
compiler. 'Pre-Defined label' looks like the most suitable
explanation for it.
The line number 2. The user defines the characteristics of the
'STACK' memory area using the 'AREA' compiler directive.
The 'AREA' directive is followed by user given 'section name'. In
this line, the section name is 'STACK'. NOINIT is an 'attribute'
means that this section is uninitialized or initialized to zero.
READWRITE is an 'attribute' which means this area has read/write
permissions.
The line number 3. It has label __stack_limit: This will
automatically take an address where the stack finishes. i.e the
lower limit of the stack address.
The line number 4. It has a key word 'Stack_Mem' followed by another
assembler directive called 'SPACE'. This defines a region of the
size of 'Stack_Size' i.e. 0x400 in this case initialized to
zero. The 'SPACE' directive always reserves an area in the memory
initialized to zero.
The line number 5. It just has a label/Symbol called __initial_sp.
Not sure if this is also a keyword, but the label __initial_sp will
now get a value of the start of the stack pointer.
Line 9,10,11 are simple, they are all trying to make the symbol
labels __Vectors, __Vectors_End and __Vectors_Size visible outside
this code, may be to the linker, using 'EXPORT' directive. 'EXPORT'
directive declares a symbol that the linker uses to resolve symbol
references anywhere in the code. 'GLOBAL' is same as 'EXPORT'
Line 11 declares a label called '__Vectors, then the directive DCD
is used. DCD directive is used to store in memory location pointed
to by the label '__Vectors', the value of the memory location
pointed to by the label '__initial_sp.
Line 12, similarly stores the next memory location by the memory
location pointed to by the label 'Reset_Handler'
Line 15. Label '__Vectors_End is declared.
Line 17. __Vectors_Size is declared which is assigned an numeric
value using EQU. This numeric value is the difference between the
memory address pointed to by the label __Vectors_End and __Vectors
Line 18. This defines another 'AREA' directive. This time the name
of the area is '.text' it is enclosed in bars like this '|.text|'
because it is starting from a special character i.e. the dot. An
attribute 'CODE' is also added to it, indicating that this area
contains executable code. That is to say it isnt data. The use of
'.text' with the code area is conventional practice. The compiler
puts this label on code areas it produce. User can look at the assembly code
and see '.text' label just above several code sections.
e.g:
.text
Reset_Handler
0x00000088:
4800
.H LDR
r0,[pc,#0] ; [0x8c] = 0x9
0x0000008a:
4700
.G
BX r0
Line 19. It declares a 'PROC' called Reset_Handler. PROC is a short
of procedure. The 'Reset_Handler' is mandatory for a start-up file
as this defines what happens when the processor is first out of
reset. This is the first thing an ARM cortex M3/M4 will execute
straight out of reset.Well, actually the first thing that the
processor would do is the stack-pointer loading form the address
0000_0000, but technically loading the stack-pointer register isn't
'executing' so its correct to say that the first thing that the ARM
processor executes out of reset is the 'Reset_Handler', a pointer to
which is stored in the program code at 0x0000_0004.
Line 20-Line24 'PROC' Reset_Handler Code.
The word 'Reset_Handler' is not a keyword. But by default Keil
compiler looks for it. The user can change it by using their own
name for it, e.g. 'MyReset_Handler'. But then the user must update
the Linker command's '--entry' option, which defaults to '--entry
Reset_Handler'.
The user may want to use a numeric value with '--entry' option e.g.
'--entry=0x0', instead of symbol like 'Reset_Handler'
The 'Reset_Handler' in the above code does nothing but jumps to
predefined function called '__main'. Note that this '__main'
function is different from the user defined 'main()' function in
c-code.
Note that there is no mention of 'Heap' in the above start-up
file. As indicated, its just a bare-minimum start-up file.
Heap definition is required when memory allocation (malloc etc) is
used in the C-programs.
SITE HOME
Keywords:
Decoding Keil Startup File
Kiel uVision assembly startup file
Bare-Minimum Assembly code for Keil uVision
Startup assembly code for ARM cortex-m processors.
Explaining the Keil Startup assembly code.
Keil Startup File explanation.
Decoding startup assembly file for arm cortex m series processors.