SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: ARM Cortex-M3 Assembly Code Examples
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm

ARM Cortex-M3 Assembly Code Examples

Graham Kruk
Last updated: October 5, 2023 9:55 am
Graham Kruk 8 Min Read
Share
SHARE

The ARM Cortex-M3 is a 32-bit RISC processor core licensed by ARM Holdings. It is intended for microcontroller use, and has been implemented by many chip manufacturers in their microcontroller products. The Cortex-M3 processor has a 3-stage pipeline and uses the ARMv7-M architecture, which includes Thumb-2 technology for improved code density. This allows it to achieve very high performance and efficiency while maintaining relatively low power consumption.

Contents
1. Basic Program Structure2. Data Processing Instructions3. Load/Store Instructions4. Branch Instructions5. Subroutine Calls6. Interrupt Handling7. Inline Assembly8. Debugging9. Startup Code10. Context Switching

Programming the Cortex-M3 in assembly language provides full control over the processor and allows developers to optimize performance for their specific application. However, assembly programming requires deep knowledge of the processor architecture and instruction set. This article provides some examples of basic Cortex-M3 assembly code to demonstrate core concepts and capabilities.

1. Basic Program Structure

All Cortex-M3 assembly programs have the same basic structure. This includes the vector table, stack pointer initialization, main program entry point label, and infinite loop at end. Here is a simple “hello world” example: .thumb .thumb_func .global _start _start: /* Vector table */ .word 0x20001000 .word Reset_Handler .word Default_Handler /* … */ /* Initialize stack pointer */ ldr sp, =0x20020000 /* Main program */ bl main b . main: /* Code here */ b . Default_Handler: b .

The vector table contains the initial stack pointer value and reset handler address. The reset handler configures the system and then calls main(). At minimum, a default handler stub is needed. The main program executes and then the infinite loop at end keeps the processor running.

2. Data Processing Instructions

Data processing instructions operate on registers and include arithmetic, logical, and move operations. Here are some examples: /* Addition */ add r0, r1, r2 /* Subtraction */ sub r3, r4, #5 /* Logical AND */ and r5, r6, r7 /* Logical OR */ orr r8, r9, #0xFF /* Move */ mov r10, #0x100

These instructions allow math operations, boolean logic, and moving immediate values into registers. Multiple addressing modes are supported for flexibility.

3. Load/Store Instructions

Load/store instructions move data between registers and memory. This includes byte, halfword, and word loads/stores. For example: /* Load byte */ ldrb r0, [r1] /* Store word */ str r2, [r3, #8] /* Load halfword */ ldrh r4, [r5, #0x10]

Loads use the source memory address in brackets. Stores use the destination address. Offsets can also be specified like above. These provide access to variables and data structures in RAM.

4. Branch Instructions

Branch instructions alter program flow by jumping to a new instruction address. Some common examples: /* Branch */ b loop /* Branch with link */ bl function /* Compare and branch */ cmp r0, #10 bgt else /* Test bit and branch */ tst r1, #0x1 beq endif

The b instruction performs a simple branch. bl branches and links, saving the return address to the LR register. Conditional branches like bgt branch if greater than based on status flags. Bit testing branches check register values.

5. Subroutine Calls

The bl instruction is used for calling subroutines and functions. Here is an example: /* Function call */ bl function /* Within function */ push {lr} /* Code */ pop {lr} bx lr function: /* Code here */ bx lr

bl branches to the function and links back to the next instruction. The function prologue pushes LR to save the return address. The epilogue pops it back and returns. This implements standard function calling procedure.

6. Interrupt Handling

The Cortex-M3 supports advanced interrupt handling with a Nested Vectored Interrupt Controller (NVIC). This allows setting priority and enabling interrupts: /* Set priority of IRQ interrupt */ ldr r0, =0xE000ED20 mov r1, #0x40 str r1, [r0] /* Enable IRQ interrupt */ ldr r0, =0xE000E100 ldr r1, [r0] orr r1, #0x2 str r1, [r0]

The NVIC registers are accessed to configure the specific IRQ interrupt priority and enable it. When an interrupt occurs, the processor will then jump to the corresponding vector handler.

7. Inline Assembly

For C programs, inline assembly allows mixing C code with ARM instructions. For example: int x; /* Inline assembly */ asm volatile( “mov r0, %[x]\n\t” “lsl r0, #2\n\t” : : [x] “r” (x) );

This shifts the variable x left 2 bits using inline ARM instructions. The input/output operands are defined to interface with the C code. This allows utilizing assembly in C programs.

8. Debugging

Debugging assembly code requires inspecting register and memory contents. The Cortex-M3 DWT (Data Watchpoint and Trace) module enables real-time debug support: /* Set watchpoint on variable */ ldr r0, =0xE0001000 mov r1, #0x100 str r1, [r0, #0x10] /* Single step */ ldr r0, =0xE000EDF0 mov r1, #0x1 str r1, [r0]

A watchpoint can be set to break on variable access. Single stepping progresses one instruction at a time for inspection. More advanced breakpoint and tracing capabilities are also available.

9. Startup Code

The Cortex-M3 startup code handles early system bring-up: .thumb_func .global Reset_Handler Reset_Handler: /* Copy data section values */ ldr r1, =_etext ldr r2, =_data_start ldr r3, =_data_end cmp r2, r3 bcs data_loop data_loop: ldr r0, [r1], #4 str r0, [r2], #4 cmp r2, r3 bcc data_loop /* Clear bss section */ ldr r2, =__bss_start__ ldr r3, =__bss_end__ mov r0, #0 bss_loop: str r0, [r2] , #4 cmp r2, r3 bcc bss_loop /* Branch to main */ bl main

This copies initialized data, clears BSS, and calls main(). Additional configuration like stack setup is also performed before main().

10. Context Switching

Context switching is used to swap between threads or tasks. This example saves context to the PSP stack pointer: /* PSP = Process Stack Pointer */ push {r4-r11} /* Save registers */ mov r0, sp /* Read PSP to r0 */ str r0, [r8] /* Store old PSP value */ ldr r0, =new_PSP /* Get new PSP */ msr psp, r0 /* Load it */ isb /* Instruction barrier */ pop {r4-r11} /* Restore registers */

The general purpose registers r4-11 are saved/restored. The old PSP is stored and new one loaded atomically. This allows Switching stacks between threads safely.

These examples demonstrate some of the key ARM Cortex-M3 assembly programming concepts. Assembly coding for this processor provides great flexibility but requires an intimate knowledge of the architecture. Many principles like subroutines, interrupts, and context switching are directly applicable to other ARM cores as well.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article STM32F407 Features & Specifications
Next Article ARM Cortex M Assembly Tutorial
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

Bootloader causing incorrect vector table and issues with PendSV

When developing embedded systems using ARM Cortex-M processors, a common…

7 Min Read

What is the cache memory in ARM processor?

Cache memory in ARM processors refers to small, fast memory…

6 Min Read

SysTick interrupt doesn’t trigger (Arm Cortex M0)

The SysTick interrupt not triggering on an ARM Cortex M0…

7 Min Read

Link Register and Program Counter

The link register and program counter are key components of…

8 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account