A Simple Example of Inline Assembler (GNAT User’s Guide for Native Platforms)

### 10.2 A Simple Example of Inline Assembler ¶

The following example generate a single assembly language statement, `nop`, which does nothing. Despite its lack of run-time effect, the example is useful in illustrating the basics of the Inline Assembler facility.

>     with System.Machine_Code; use System.Machine_Code;
>     procedure Nothing is
>     begin
>        Asm ("nop");
>     end Nothing;

`Asm` is a procedure declared in package `System.Machine_Code`; here it takes one parameter, a ‘template string’ that must be a static expression that produces the generated instruction. `Asm` may be regarded as a compile-time procedure that parses the template string and any additional parameters (none, in this case) and generates one or more assembly language instructions.

The examples in this chapter will illustrate several of the forms for invoking `Asm`; a complete specification of the syntax is found in the `Machine_Code_Insertions` section of the GNAT Reference Manual.

Under the standard GNAT conventions, you should put the `Nothing` procedure in a file named `nothing.adb`. You can build the executable in the usual way:

>     $ gnatmake nothing

However, the interesting aspect of this example is not its run-time behavior but rather the generated assembly code. To see this output, invoke the compiler as follows:

>     $ gcc -c -S -fomit-frame-pointer -gnatp nothing.adb

where the options are:

- `-c`

    compile only (no bind or link)

- `-S`

    generate assembler listing

- `-fomit-frame-pointer`

    do not set up separate stack frames

- `-gnatp`

    do not add runtime checks

This gives a human-readable assembler version of the code. The resulting file has the same name as the Ada source file but with a `.s` extension. In our example, the file `nothing.s` has the following contents:

>     .file "nothing.adb"
>     gcc2_compiled.:
>     ___gnu_compiled_ada:
>     .text
>        .align 4
>     .globl __ada_nothing
>     __ada_nothing:
>     #APP
>        nop
>     #NO_APP
>        jmp L1
>        .align 2,0x90
>     L1:
>        ret

The assembly code you included is clearly indicated by the compiler, between the `#APP` and `#NO_APP` delimiters. The character before the ‘APP’ and ‘NOAPP’ can differ on different targets. For example, GNU/Linux uses ‘#APP’ while on NT you will see ‘/APP’.

If you make a mistake in your assembler code (such as using the wrong size modifier or using a wrong operand for the instruction) GNAT will report this error in a temporary file, which is deleted when the compilation is finished. Generating an assembler file will help in such cases, since you can assemble this file separately using the `as` assembler that comes with gcc.

Assembling the file using the command

>     $ as nothing.s

will give you error messages whose lines correspond to the assembler input file, so you can easily find and correct any mistakes you made. If there are no errors, `as` generates an object file called `nothing.out`.