6.43.1 Basic Asm — Assembler Instructions Without Operands

A basic asm statement has the following syntax:

asm [ volatile ] ( AssemblerInstructions )

The asm keyword is a GNU extension. When writing code that can be compiled with -ansi and the various -std options, use __asm__ instead of asm (see Alternate Keywords).

Qualifiers

volatile
The optional volatile qualifier has no effect. All basic asm blocks are implicitly volatile.

Parameters

AssemblerInstructions
This is a literal string that specifies the assembler code. The string can contain any instructions recognized by the assembler, including directives. GCC does not parse the assembler instructions themselves and does not know what they mean or even whether they are valid assembler input.

You may place multiple assembler instructions together in a single asm string, separated by the characters normally used in assembly code for the system. A combination that works in most places is a newline to break the line, plus a tab character (written as ‘\n\t’). Some assemblers allow semicolons as a line separator. However, note that some assembler dialects use semicolons to start a comment.

Remarks

Using extended asm typically produces smaller, safer, and more efficient code, and in most cases it is a better solution than basic asm. However, there are two situations where only basic asm can be used:

  • Extended asm statements have to be inside a C function, so to write inline assembly language at file scope (“top-level”), outside of C functions, you must use basic asm. You can use this technique to emit assembler directives, define assembly language macros that can be invoked elsewhere in the file, or write entire functions in assembly language.
  • Functions declared with the naked attribute also require basic asm (see Function Attributes).

Safely accessing C data and calling functions from basic asm is more complex than it may appear. To access C data, it is better to use extended asm.

Do not expect a sequence of asm statements to remain perfectly consecutive after compilation. If certain instructions need to remain consecutive in the output, put them in a single multi-instruction asm statement. Note that GCC's optimizers can move asm statements relative to other code, including across jumps.

asm statements may not perform jumps into other asm statements. GCC does not know about these jumps, and therefore cannot take account of them when deciding how to optimize. Jumps from asm to C labels are only supported in extended asm.

Under certain circumstances, GCC may duplicate (or remove duplicates of) your assembly code when optimizing. This can lead to unexpected duplicate symbol errors during compilation if your assembly code defines symbols or labels.

Since GCC does not parse the AssemblerInstructions, it has no visibility of any symbols it references. This may result in GCC discarding those symbols as unreferenced.

The compiler copies the assembler instructions in a basic asm verbatim to the assembly language output file, without processing dialects or any of the ‘%’ operators that are available with extended asm. This results in minor differences between basic asm strings and extended asm templates. For example, to refer to registers you might use ‘%eax’ in basic asm and ‘%%eax’ in extended asm.

On targets such as x86 that support multiple assembler dialects, all basic asm blocks use the assembler dialect specified by the -masm command-line option (see x86 Options). Basic asm provides no mechanism to provide different assembler strings for different dialects.

Here is an example of basic asm for i386:

/* Note that this code will not compile with -masm=intel */
#define DebugBreak() asm("int $3")

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.4.0/gcc/Basic-Asm.html