Skip to main content
PPopo
Associate III
April 4, 2021
Solved

ARM Cortex M4 assembly questions

  • April 4, 2021
  • 3 replies
  • 2450 views

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. 

  

This topic has been closed for replies.
Best answer by Tesla DeLorean

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

3 replies

Tesla DeLorean
Guru
April 4, 2021

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

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Tesla DeLoreanBest answer
Guru
April 4, 2021

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

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
PPopo
PPopoAuthor
Associate III
April 4, 2021

Thanks.