Assembly Primer
Assembly Directives
- Thumb - placed at the top of the file to specify that code is generated with Thumb instructions.
- CODE - Denotes the section for machine instructions (ROM).
- DATA Denotes the section for global variables(RAM).
- AREA -Instructs the assembler to assemble a new code or data section.
- SPACE Reserves a block of memory and fills it with zeros.
- ALIGN-Used to ensure next object aligns properly.
- EXPORT – to make an object accessible from another file
- GLOBAL – Same meaning as EXPORT
- IMPORT – to access an “exported” object
- END – Placed at the end of each file
- DCB – Places byte (8-bits) sized constant in memory
- DCW – Places a half-word (16-bits) sized constant into memory
- DCD – Places a word (32-bits) sized constant into memory
- EQU – To give a symbolic name to a numeric constant.
- |.text| Makes assembly code callable by C
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
EXPORT __main
__main
BL GPIO_Init
Blink
MOVW R1, #LED_GREEN
STR R1, [R2]
LDR R3, =ONESEC
BL Delay
MOVW R1, #LED_BLUE
STR R1, [R2]
LDR R3, =HSEC
BL Delay
MOVW R1, #LED_RED
STR R1, [R2]
LDR R3, =HSEC
BL Delay
MOVW R1, #LED_ORANGE
STR R1, [R2]
LDR R3, =FSEC
BL Delay
B Blink
GPIO_Init
LDR R0, =RCC_AHB1ENR ; R0 points to peripheral clock register
LDR R1, [R0] ; Load Peripheral clock register into R1
ORR R1, R1, GPIOIDEN ; Enable GPIO port D clock
STR R1, [R0] ; Store result back
LDR R0, =GPIOD_MODER ; R0 points to PORTD configuration register
LDR R1, =(MODER15_OUT | MODER14_OUT | MODER13_OUT | MODER12_OUT)
STR R1, [R0] ; Set pins 15,14,13,12 as output
MOV R1, #0
LDR R2, =GPIOD_ODR ; GPIO output data register
BX LR
Delay
SUBS R3, R3, #1
BNE Delay
BX LR
ALIGN
;-------------------------------
; Constants and Equates
;-------------------------------
RCC_BASE EQU 0x40023800
RCC_AHB1ENR EQU 0x40023830
GPIOD_BASE EQU 0x40020C00
GPIOD_MODER EQU 0x40020C00
GPIOD_ODR EQU 0x40020C14
GPIOIDEN EQU 1 << 3
MODER15_OUT EQU 1 << 30
MODER14_OUT EQU 1 << 28
MODER13_OUT EQU 1 << 26
MODER12_OUT EQU 1 << 24
LED_BLUE EQU 1 << 15
LED_RED EQU 1 << 14
LED_ORANGE EQU 1 << 13
LED_GREEN EQU 1 << 12
DELAY EQU 0x000F
ONESEC EQU 5333333
HSEC EQU 266667
FSEC EQU 106667
END
MOV Instruction:
-
Used to move data within the processor without accessing memory.
-
Can only move 8-bit immediate values.
-
Cannot move immediate values to high registers (R8-R15).
-
Example:
MOV R0, #150 ; valid, 8-bit immediate MOV R1, R2 ; valid, register to register -
Incorrect usage:
MOV R0, #256 ; invalid, out of 8-bit range MOV R8, #3 ; invalid, cannot move immediate to high register
LDR (Load Register):
Loads a 32-bit value into a register from memory or a constant.
Example:
LDR R0, =0xFFFF ; Loads 0xFFFF into R0
LDR R1, [R2] ; Loads value pointed to by R2 into R1
STR (Store Register):
Stores a register’s value into memory.
Example:
STR R0, [R1] ; Stores R0 value into memory pointed by R1
B (Branch):
Unconditional jump to a label/address.
Example:
B loop ; Jumps to 'loop' label
BL (Branch with Link):
Calls a subroutine and saves return address in LR.
Example:
BL GPIOF_Init ; Calls GPIOF_Init subroutine
BX (Branch and Exchange):
Branches to address in a register, possibly switching instruction set.
Example:
BX LR ; Returns from subroutine (uses Link Register)
NOP (No Operation):
Does nothing; used for timing or alignment.
Example:
NOP ; No operation performed
ORR (Logical OR)
Performs a bitwise OR between two registers.
Example:
// R0 = 0b1010, R1 = 0b1100
ORR R2, R0, R1 // R2 = 0b1110
AND (Logical AND)
Performs a bitwise AND between two registers.
Example:
// R0 = 0b1010, R1 = 0b1100
AND R2, R0, R1 // R2 = 0b1000
EOR (Exclusive OR)
Performs a bitwise XOR between two registers.
Example:
// R0 = 0b1010, R1 = 0b1100
EOR R2, R0, R1 // R2 = 0b0110