2021-04-04 12:16 AM
Hello everyone,
I'm just starting to learn assembly for the ARM architecture. I'm also in general a beginner with the assembly language I have just some minor experience with the x86 assembly but that's about it.
I'm following a course on Udemy and I have this code which explains how to create an assembly project without the use of the startup.s file generated by Keil.
This is why I'm doing stuff like setting up the vector table and stack initialization in the main.s file.
Stack_Size EQU 0x00000100 ;Define stack size of 256 bytes
;Here we are just telling the processor to reserve a section of RAM called STACK for us, nothing else.
AREA STACK,NOINIT,READWRITE,ALIGN=3
; Why do we need the StackMem label for this?
StackMem SPACE Stack_Size ;the SPACE directive reserves a zeroed block of memory. Fill 0x100 bytes with 0.(starting at address of StackMem label?????)
AREA RESET,DATA, READONLY ;Reserve a section in RAM called RESET
EXPORT __Vectors
__Vectors
DCD StackMem +Stack_Size ;Allocates 1 word(32b) containing Stack_Size + the address of the label StackMem. Stack pointer when stack is empty.
DCD Reset_Handler ;Allocates 1 word after StackMem + Stack_Size
ALIGN ;sets the current location to the next word(4 byte) boundary
AREA SimpleProject,CODE,READONLY,ALIGN=2
ENTRY ;Does this mean that after executing Reset_Handler routine we should arrive here????
EXPORT Reset_Handler ; Why do we export the Reset_Handler here why don't we export it after the Reset_Handler label???????
Reset_Handler
MOV R5,#0x1234
MOV R3,#0x1234
ADD R6,R5,R3
STOP B STOP
END
The questions are also in the code as comments but I will ask them in text here also. Please ignore the comments from the code, they are just for me. I'm sorry if some of them make no sense for someone more knowledgeable :) . Here are the questions:
1. Why do we need this line?
AREA STACK,NOINIT,READWRITE,ALIGN=3
I understand what it does that we are reserving 256 bytes for an area called STACK but I do not understand how is that used in our program since we are not using
the STACK(capital case) name anywhere else in the program. I have read the documentation on AREA directive but I still do not know why that line is needed.
2. On this line:
StackMem SPACE Stack_Size
we are filling the 256 bytes reserved for the stack with 0. Why do we need the StackMem label there why can't we just do SPACE Stack_Size without it?
3. What does this line:
DCD StackMem +Stack_Size
do exactly? Does it allocate 1 word at the address of StackMem label which contains the value 256 which is the number of bytes reserved for the stack?
And when we do right after the above line:
DCD Reset_Handler
does this mean we are allocating 1 word which will contain the address of the label Reset_Handler declared below?
4. The 'Entry" derective means that after executing the Reset_Handler procedure which we declare below the code will start from there?
5. Why do we export Reset_Handler before we actually declare the Reset_Handler label below?
Thank you for reading! Please help me understand these things and again, I apologize if these questions make no sense but I'm a total beginner when it comes to ARM assembly.
Solved! Go to Solution.
2021-04-04 08:36 AM
AREA is more akin to the SEGMENT/SECTION on x86, it is a way to direct content to specific places, usually via the scatter file or linker script. ie where you keep CODE, DATA, and BSS sections separate.
Gets more complicated on the Cortex-M parts as large constants which would be inlined or immediates in other architectures are stored in a "literal pool" outside the normal flow of code, or just beyond the function's code, via a short PC relative load.
See line 985 for literals uses on 966,968,971,979, ie ldr r2, [pc, #248]
..
965 00000438 4311 orrs r1, r2
966 0000043A 4A08 ldr r2, =QUADSPI
967 0000043C 6011 str r1, [r2, #0]
968 0000043E 4A09 ldr r2, =QUADSPI+4
969 00000440 6812 ldr r2, [r2, #0]
970 00000442 0011 lsls r1, r2, #0
971 00000444 4A08 ldr r2, =0xFFE0F7FE
972 00000446 4011 ands r1, r2
973 00000448 6902 ldr r2, [r0, #16]
974 0000044A 68C3 ldr r3, [r0, #12]
975 0000044C EA53 4202 orrs.w r2, r3, r2, lsl #16
976 00000450 6883 ldr r3, [r0, #8]
977 00000452 431A orrs r2, r3
978 00000454 4311 orrs r1, r2
979 00000456 4A03 ldr r2, =QUADSPI+4
980 00000458 6011 str r1, [r2, #0]
981 0000045A 4770 bx lr
982 0000045C ENDP ; QUADSPI_Init
983 0000045C
984 0000045C ALIGN
985 0000045C A0001000
00FFFFCF
A0001004
FFE0F7FE LTORG
986 0000046C
987 0000046C QUADSPI_ComConfig_Init
PROC
2021-04-04 07:37 AM
The vector table provides a list of addresses, easily/efficiently loadable by the processor
The first two values being SP and PC (R15)
The stack moves downward, and predecrements, so the address for the initial SP is just beyond the allocated space, ie base+length
To find the end, you need a symbol for the beginning.
Global variables have scope beyond the file, allowing the linker to bind between source files.
The order in which you define the name, and export it, are not critical in this assembler, others might be.
The Entry point flags a point for the linker which it outputs for the debugger, and in the .HEX/.AXF file
2021-04-04 07:47 AM
Thanks.
2021-04-04 08:36 AM
AREA is more akin to the SEGMENT/SECTION on x86, it is a way to direct content to specific places, usually via the scatter file or linker script. ie where you keep CODE, DATA, and BSS sections separate.
Gets more complicated on the Cortex-M parts as large constants which would be inlined or immediates in other architectures are stored in a "literal pool" outside the normal flow of code, or just beyond the function's code, via a short PC relative load.
See line 985 for literals uses on 966,968,971,979, ie ldr r2, [pc, #248]
..
965 00000438 4311 orrs r1, r2
966 0000043A 4A08 ldr r2, =QUADSPI
967 0000043C 6011 str r1, [r2, #0]
968 0000043E 4A09 ldr r2, =QUADSPI+4
969 00000440 6812 ldr r2, [r2, #0]
970 00000442 0011 lsls r1, r2, #0
971 00000444 4A08 ldr r2, =0xFFE0F7FE
972 00000446 4011 ands r1, r2
973 00000448 6902 ldr r2, [r0, #16]
974 0000044A 68C3 ldr r3, [r0, #12]
975 0000044C EA53 4202 orrs.w r2, r3, r2, lsl #16
976 00000450 6883 ldr r3, [r0, #8]
977 00000452 431A orrs r2, r3
978 00000454 4311 orrs r1, r2
979 00000456 4A03 ldr r2, =QUADSPI+4
980 00000458 6011 str r1, [r2, #0]
981 0000045A 4770 bx lr
982 0000045C ENDP ; QUADSPI_Init
983 0000045C
984 0000045C ALIGN
985 0000045C A0001000
00FFFFCF
A0001004
FFE0F7FE LTORG
986 0000046C
987 0000046C QUADSPI_ComConfig_Init
PROC