Next: , Previous: Basic Assembler Syntax, Up: Inline Assembler


12.2 A Simple Example of Inline Assembler

The following example will generate a single assembly language statement, nop, which does nothing. Despite its lack of run-time effect, the example will be 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 and that will form the generated instruction. Asm may be regarded as a compile-time procedure that parses the template string and additional parameters (none here), from which it generates a sequence of 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, the Nothing procedure should be 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:

This gives a human-readable assembler version of the code. The resulting file will have 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 will be 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' will generate an object file nothing.out.