How to Use ARM Assembly with C Code: Syntax and Example
You can use ARM assembly in C code by writing inline assembly with the
asm keyword or by linking separate assembly files compiled with an ARM assembler. Inline assembly lets you embed ARM instructions directly inside C functions, while separate files require proper function declarations and linking.Syntax
ARM assembly can be included in C code mainly in two ways: inline assembly and separate assembly files.
- Inline assembly: Use the
asmor__asm__keyword followed by the assembly instructions in quotes. - Separate files: Write assembly code in a
.sfile, assemble it with an ARM assembler, then link it with your C code.
Inline assembly syntax example:
asm ("assembly instructions");For more complex inline assembly, you can specify input/output operands and clobbered registers.
armasm
asm ("mov r0, #1\n" "bx lr");
Example
This example shows a C function calling an ARM assembly function that adds two integers and returns the result.
c
#include <stdio.h> // Declaration of the assembly function int add_numbers(int a, int b); int main() { int result = add_numbers(5, 7); printf("Result: %d\n", result); return 0; } // Assembly code in separate file (add_numbers.s): // // .global add_numbers // add_numbers: // ADD r0, r0, r1 // BX lr
Output
Result: 12
Common Pitfalls
Common mistakes when mixing ARM assembly with C include:
- Not preserving registers that the C compiler expects to remain unchanged.
- Incorrectly declaring assembly functions in C, causing calling convention mismatches.
- Forgetting to mark assembly functions as
.globalto make them visible to the linker. - Using inline assembly without specifying clobbered registers, leading to unpredictable behavior.
Example of wrong inline assembly usage:
asm ("mov r0, #1"); // Missing clobber list, may cause issuesCorrect usage with clobber list:
asm volatile ("mov r0, #1" : : : "r0");Quick Reference
| Concept | Description | Example |
|---|---|---|
| Inline Assembly | Embed ARM instructions inside C using asm keyword | asm volatile ("mov r0, #1" : : : "r0"); |
| Separate Assembly File | Write ARM code in .s file, assemble and link | .global func\nfunc:\n ADD r0, r0, r1\n BX lr |
| Function Declaration | Declare assembly functions in C to call them | int func(int a, int b); |
| Preserving Registers | Save registers if modified to avoid bugs | Push/pop or specify clobbers in inline asm |
| Clobber List | Tell compiler which registers are changed | asm volatile ("..." : : : "r0", "r1"); |
Key Takeaways
Use the asm keyword for inline ARM assembly inside C functions.
Declare and link separate assembly files properly to call ARM code from C.
Always specify clobbered registers in inline assembly to avoid compiler errors.
Preserve registers according to ARM calling conventions to prevent bugs.
Mark assembly functions as global to make them accessible from C.