До сих пор мы рассматривали программы на встроенном ассемблере, которые способны осуществлять только вывод информации.
Однако также часто возникает необходимость в осуществлении ввода информации в программу которая написана на встроенном ассемблере.
Рассмотрим пример программы, которая использует функцию написанную на встроенном ассемблере, причем, эта функция принимает входное значение своего параметра, увеличивает это значение на единицу, а затем возвращает его в качестве результата.
| with Interfaces; use Interfaces; with Ada.Text_IO; use Ada.Text_IO; with System.Machine_Code; use System.Machine_Code;
procedure Inc_It is function Increment (Value : Unsigned_32) return Unsigned_32 is Result : Unsigned_32; begin Asm ("incl %0", Inputs => Unsigned_32'Asm_Input ("a", Value), Outputs => Unsigned_32'Asm_Output ("=a", Result)); return Result; end Increment; Value : Unsigned_32; begin Value := 5; Put_Line ("Value before is" & Value'Img); Value := Increment (Value); Put_Line ("Value after is" & Value'Img); end Inc_It; |
Следует заметить, что на данном этапе принцип кодирования инструкций встроенного ассемблера уже должен быть понятен:
| Asm ("incl %0", Inputs => Unsigned_32'Asm_Input ("a", Value), Outputs => Unsigned_32'Asm_Output ("=a", Result)); |
Как видно из этого примера, параметр вывода описан так же как и ранее, определяя, что результат, полученный в регистре eax, будет сохранен в переменной Result.
Описание параметра ввода во многом похоже на описание параметра вывода, но использует атрибут 'Asm_Input вместо атрибута 'Asm_Output.
Кроме того, при описании параметра ввода, отсутствует указание ограничения =, указывающего на вывод значения.
Также как и в случае параметров вывода, допускается наличие множества параметров ввода.
Отсчет параметров (%0, %1, ...) начинается с первого параметра ввода и продолжается при перечислении инструкций вывода.
|
Asm ("incl %0", Inputs => Unsigned_32'Asm_Input ("a", Value), Outputs => Unsigned_32'Asm_Output ("=a", Result)); |
|
_inc_it__increment.1: subl $4,%esp movl 8(%esp),%eax #APP incl %eax #NO_APP movl %eax,%edx movl %ecx,(%esp) addl $4,%esp ret |