10.1 Inline Assembly

armclang provides an inline assembler that enables you to write assembly language sequences in C and C++ language source files. The inline assembler also provides access to features of the target processor that are not available from C or C++.

You can use inline assembly in two contexts:

  • File-scope inline assembly statements.
    __asm(".global __use_realtime_heap");
  • Inline assembly statement within a function.
    void set_translation_table(void *table) {
        __asm("msr TTBR0_EL1, %0"
          : "r" (table));

Both syntaxes accept assembly code as a string. Write your assembly code in the syntax that the integrated assembler accepts. For both syntaxes, the compiler inserts the contents of the string into the assembly code that it generates. All assembly directives that the integrated assembler accepts are available to use in inline assembly. However, the state of the assembler is not reset after each block of inline assembly. Therefore, avoid using directives in a way that affects the rest of the assembly file, for example by switching the instruction set between A32 and T32. See Chapter 9 armclang Integrated Assembler.

Implications for inline assembly with optimizations

You can write complex inline assembly that appears to work at some optimization levels, but the assembly is not correct. The following examples describe some situations when inline assembly is not guaranteed to work:

  • Including an instruction that generates a literal pool. There is no guarantee that the compiler can place the literal pool in the range of the instruction.
  • Using or referencing a function only from the inline assembly without telling the compiler that it is used. The compiler treats the assembly as text. Therefore, the compiler can remove the function that results in an unresolved reference during linking. The removal of the function is especially visible for LTO, because LTO performs whole program optimization and is able to remove more functions.

    For file-scope inline assembly, you can use the __attribute((used)) function attribute to tell the compiler that a function is used. For inline assembly statements, use the input and output operands.

For large blocks of assembly code where the overhead of calling between C or C++ and assembly is not significant, Arm recommends using a separate assembly file, which does not have these limitations.

Non-ConfidentialPDF file icon PDF versionDUI0774J
Copyright © 2014–2017, 2019 Arm Limited or its affiliates. All rights reserved.