Энциклопедия Turbo Pascal. Главы 1-4 - Встроенный код ассемблера

ОГЛАВЛЕНИЕ

Встроенный код ассемблера

В отличие от стандартного Паскаля в Турбо Паскале предусматривается возможность непосредственного включения кода на ассемблере. Таким образом, нет необходимости составлять отдельную внешнюю подпрограмму. Такой подход имеет два преимущества: во-первых, программист не должен писать код,  реализующий связь между программами; во-вторых, весь код расположен в одном месте, что делает простой сопровождение программы. Единственный недостаток заключается в том, что встроенный код ассемблера имеет неудобный формат.

Оператор "inline" позволяет внутри программы на Турбо Паскале использовать код на ассемблере.  Общая форма этого оператора будет следующей:

     inline (значение/.../значение);  

где "значение" представляет собой любую правильную инструкцию ассемблера или данные.  Для ссылки на счетчик адреса может использоваться звездочка.  (В ассемблере процессора  8088  для этой цели используется валютный знак.  Поскольку в Турбо Паскале валютный знак используется для шестнадцатиричных чисел,  то для обозначения счетчика адреса используется звездочка).

Для малых значений,  которые могут разместиться в одном байте,  используется только один байт. В противном случае для хранения переменной используются два байта.  Если вы хотите поступить иначе, то следует воспользоваться директивами ">" и "<". Если перед значением стоит знак меньше,  то будет использован только младший байт.  Если перед значением стоит знак больше,  то будет сформировано двубайтовое слово с нулевым старшим байтом.  Например, <$1234 приведет к формированию только одного байта со значением $34, a >$12 приведет к формированию двух байт со значением $
0012.

Следующая короткая программа перемножает два целых числа, используя функцию "Mul", которая использует код на ассемблере для выполнения действительного умножения.  Сравните эту программу с внешней подпрограммой "xmul",  которая рассматривалась в предыдущем разделе.

     { пример встроенного кода ассемблера }
     program asm_inline;

     var
       a, b, c: integer;

     function Mul(x, y: integer): integer;
     begin
       inline($80/$46/$04/   {mov ax,[bp]+4}
              $F6/366/$06/   {mul [bp]+6   }
              $89/$EC/       {mov sp,bp}
              $56/           {pop bp}
              $02/$06/$00/   {ret 6}

       end;

     begin
       a: = 10;
       b: = 20;
       c: = Mul(a,b);
       WriteLn(c);
     end.

В данном случае компилятор Турбо Паскаля автоматически генерирует код для возврата из функции.  Когда компилятор встречает оператор "inline",  в этом месте он генерирует указанные оператором машинные инструкции.

Часто встроенный код ассемблера используется для обеспечения связи с оборудованием,  которое не поддерживается непосредственно в языке Турбо Паскаль. Например, приводимая ниже подпрограмма может использоваться для включения вентилятора,  когда показание датчика температуры достигнет определенной величины.  В данном случае предполагается,  что установка в единичное значение порта 200 приводит к включению вентилятора:

     procedure fan(temp:integer);
    {вентилятор включается,  когда температура достигнет 100
              градусов }
     begin
       if temp>=100 then
         inline(100/00/01/  {mov AX,1}
                $E7/$C8);   {out 200,AX}
     end;

Следует помнить,  что компилятор Турбо Паскаля обеспечивает необходимый код для входа и выхода из функции. Пользователю необходимо лишь обеспечить тело функции и придерживаться соглашений о связях при доступе к аргументам.

При использовании указанного метода создается машинно-зависимый код, что затрудняет перенос программы на новую машину или в среду новой операционной системы.  Однако в тех случаях,  когда нельзя обойтись без кода ассемблера, применение указанного метода оправдано.