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