Input Variables in Inline Assembler (GNAT User’s Guide for Native Platforms)

### 10.4 Input Variables in Inline Assembler ¶

The example in this section illustrates how to specify the source operands for assembly language statements. The procedure simply increments its input value by 1:

>     with Interfaces; use Interfaces;
>     with Ada.Text_IO; use Ada.Text_IO;
>     with System.Machine_Code; use System.Machine_Code;
>     procedure Increment is

>        function Incr (Value : Unsigned_32) return Unsigned_32 is
>           Result : Unsigned_32;
>        begin
>           Asm ("incl %0",
>                Outputs => Unsigned_32'Asm_Output ("=a", Result),
>                Inputs  => Unsigned_32'Asm_Input ("a", Value));
>           return Result;
>        end Incr;

>        Value : Unsigned_32;

>     begin
>        Value := 5;
>        Put_Line ("Value before is" & Value'Img);
>        Value := Incr (Value);
>       Put_Line ("Value after is" & Value'Img);
>     end Increment;

The `Outputs` parameter to `Asm` specifies that the result is in the `eax` register and that it is to be stored in the `Result` variable.

The `Inputs` parameter looks much like the `Outputs` parameter, but with an `Asm_Input` attribute. The `"="` constraint, indicating an output value, is not present.

You can have multiple input variables in the same way you can have more than one output variable.

The parameter count (%0, %1) etc, still starts at the first output statement, and continues with the input statements.

Just as the `Outputs` parameter causes the register to be stored into the target variable after execution of the assembler statements, the `Inputs` parameter causes its variable to be loaded into the register before execution of the assembler statements.

Thus the effect of the `Asm` invocation is:

- load the 32-bit value of `Value` into `eax`
- execute the `incl %eax` instruction
- store the contents of eax into the `Result` variable

The resulting assembler file (with `-O2` optimization) contains:

>     _increment__incr.1:
>        subl $4,%esp
>        movl 8(%esp),%eax
>     #APP
>        incl %eax
>     #NO_APP
>        movl %eax,%edx
>        movl %ecx,(%esp)
>        addl $4,%esp
>        ret