Assembly Primer

Assembly Directives

        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:

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