Home | Projects | Notes > ARM Cortex-M3/M4 Processor > ARM GCC Inline Assembly
Inline assembly code is used to write pure assembly code inside a C program. It is used in order to access the processor core registers such as general purpose register, stack pointer, link register, program counter, or special registers.
Inline assembly statement syntax is compiler-specific.
GCC-specific syntax is as follows:
xxxxxxxxxx31__asm volatile("<assembly code>");2 --------3 optional keywordFor example,
xxxxxxxxxx61/* assembly instruction */2mov r0, r13 4/* inline assembly statement inside C program (GCC specific) */ 5__asm volatile("mov r0, r1"); 6asm volatile("mov r0, r1"); /* omitting the leading '__' also works */Combining multiple assembly instructions in one inline assembly statement:
xxxxxxxxxx161void func_add(void)2{3 /*4 __asm volatile("ldr r0, [r1]");5 __asm volatile("ldr r1, [r2]");6 __asm volatile("add r1, r0");7 __asm volatile("str r1, [r3]");8 */9 10 __asm volatile(11 "ldr r0, [r1]\n\t" // every line has to be wrapped by "" and terminated with \n\t 12 "ldr r1, [r2]\n\t" // no comma separation */13 "add r1, r0\n\t"14 "str r1, [r3]\n\t"15 ); 16}Why is inline assembly syntax necessary?
There may be some cases where you cannot accomplish things without using inline assembly code:
e.g., To move the content of C variable data to ARM register r0, to move the content of the CONTROL resgister to the C variable control_reg.

Remember! This only applies to GCC. Other compilers like ARM CC or IAR uses different format.
Example:
xxxxxxxxxx31__asm volatile("mov r0, r1"); // specifying 'code' only (you can omit the ':' only when2 // omitting does not cause confusion)3__asm volatile("mov r0, r1":::); // specifying empty sections along with the code Each input and output operand is described by a constraint string followed by a C expression in parentheses.
Input/output operand format:
xxxxxxxxxx11"<constraint string>" (<C expression>) Constraint string = Constraint modifier + Constraint character
"Constraint character"
Controls whether a register should be used or whether an immediate value should be used with the instruction
"Constraint modifier":
= - Write-only operand, usually used for all output operands
+ - Read-write operand, must be listed as an output operand
& - A register that should be used for output only
Example 1: Move the content of C variable val to ARM register r0. (Data copy)
xxxxxxxxxx51// instruction : mov2// source : a C variable 'val' (INPUT operand)3// destination : r0 (ARM core register)4
5__asm volatile("mov r0, %0": : "r"(val));Code
Operand indexing using % sign followed by a digit
%0 refers to the first operand
%1 refers to the second and so forth
The compiler will replace
%0by the first operand that appears in the following output/input operand list. In this case the first operand will beval.Input operand list
constraint string:
"r"Here,
ris the constraint character which tells the compiler that a register operand is allowed provided that it is in a general register. See Simple Constraints.C expression:
val(C variable)Input operands are always read-only.
Example 2: Move the content of CONTROL register to C variable control_reg. (Reading the contents of a special purpose register)
xxxxxxxxxx91// CONTROL register is a special register of the ARM core.2// To read CONTROL register you have to use MRS instruction.3
4// instruction : mrs5// source : CONTROL register6// destination : A C variable 'control_reg' (OUTPUT operand)7
8uint23_t control_reg;9__asm volatile("mrs %0, CONTROL": "=r"(control_reg)::);Code
mrs- Move from special register to (general purpose) register
msr- Move from (general purpose) register to special registerOutput operand list
constraint string:
"=r"Here,
ris the constraint character which tells the compiler that a register operand is allowed provided that it is in a general register. See Simple Constraints.C expression:
val(C variable)
Example 3: Copy the content of C variable var1 to var1
xxxxxxxxxx61// instruction : mov2// source : A C variable 'var1' (INTPUT operand)3// destination : A C variable 'var2' (OUTPUT operand)4
5int var1 = 10, var2;6__asm("mov %0, %1": "=r"(var2): "r"(var1)); Code
volatilekeyword can be omitted if not necessaryOutput operand list
Destination has to be the output operand
var2(write-only)
%0refers to"=r"(var2)Input operand list
Source has to be the input operand
var1(read-only)
%1refers to"r"(var1)
Example 4: Copy the contents of a pointer into another variable
xxxxxxxxxx41int p1, *p2;2
3p2 = (int *)0x20000008;4__asm volatile("ldr %0, [%1]": "=r"(p1): "r"(p2)); // p1 = *p2;
Nayak, K. (2022). Embedded Systems Programming on ARM Cortex-M3/M4 Processor [Video file]. Retrieved from https://www.udemy.com/course/embedded-system-programming-on-arm-cortex-m3m4/