8.1.1. Invoking the inline assembler

The ARM C compilers support inline assembly language with the __asm specifier.

The ARM C++ compilers support the asm syntax proposed in the Draft C++ Standard, with the restriction that the string literal must be a single string. For example:

asm("instruction[;instruction]");

The asm syntax is supported by the C++ compilers when compiling both C and C++. The asm statement must be inside a C or C++ function. Do not include comments in the string literal. An asm statement can be used anywhere a C or C++ statement is expected.

In addition to the asm syntax, ARM C++ supports the C compiler __asm syntax when used with both asm and __asm.

The inline assembler is invoked with the assembler specifier, and is followed by a list of assembler instructions inside braces. For example:

__asm
{
	instruction [; instruction]
	...
	[instruction]
}

If two instructions are on the same line, you must separate them with a semicolon. If an instruction is on multiple lines, line continuation must be specified with the backslash character (\). C or C++ comments may be used anywhere within an inline assembly language block.

String copying example

Example 8.1 shows how to use labels and branches in a string copy routine. The syntax of labels inside assembler blocks is the same as in C. Function calls that use BL from inline assembly language must specify the input registers, the output registers, and the corrupted registers. In this example, the inputs to my_strcpy are r0 and r1, there are no outputs, and the default APCS registers {r0-r3, r12, lr, PSR} are corrupted.

Example 8.1. 

#include <stdio.h>
void my_strcpy(char *src, char *dst)
{
    int ch;
    __asm
    {
    loop:
#ifndef __thumb
        // ARM version
        LDRB    ch, [src], #1
        STRB    ch, [dst], #1
#else
        // Thumb version
        LDRB    ch, [src]
        ADD     src, #1
        STRB    ch, [dst]
        ADD     dst, #1
#endif
        CMP     ch, #0
        BNE     loop
    }
}
int main(void)
{
    char a[] = "Hello world!";
    char b[20];
__asm
    {
        MOV     R0, a
        MOV     R1, b
        BL      my_strcpy, {R0, R1}, {}, {}
    }
    printf("Original string: %s\n", a);
    printf("Copied   string: %s\n", b);
    return 0;
}
Copyright © 1997, 1998 ARM Limited. All rights reserved.ARM DUI 0040D
Non-Confidential