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 Machine Code Insertions.
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:
-c
-S
-fomit-frame-pointer
-gnatp
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.