Энциклопедия 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;
Следует помнить, что компилятор Турбо Паскаля обеспечивает необходимый код для входа и выхода из функции. Пользователю необходимо лишь обеспечить тело функции и придерживаться соглашений о связях при доступе к аргументам.
При использовании указанного метода создается машинно-зависимый код, что затрудняет перенос программы на новую машину или в среду новой операционной системы. Однако в тех случаях, когда нельзя обойтись без кода ассемблера, применение указанного метода оправдано.