Иллюстрированный самоучитель по Tirbo Pascal



              

Использование встроенных машин кодов - часть 2


Function InPort(Port: Word): Word; 

var

pp: Word;

cc:Char; 

egin

pp:=port; 

inline (

$8b/$96/pp/ { mov DX,pp[bp] }

$EC/ { IN AX,DX }

$88/$86/cc); {mov cc[bp],AX}

InPort:=ord(cc); 

end;

Procedure OutPort(Port,Bt: Word); 

var

pp: Word;

cc:Char; 

begin

pp:=port;

cc:=chr(Bt);

inline (

$8a/$86/cc/ { mov AX,cc[bp] }

$8b/$96/pp/ { mov DX,pp[bp] }

$EE) { OUT DX,AX } 

end;

Операторы INLINE могут произвольным образом смешиваться с другими операторами Турбо Паскаля, однако при выходе из процедуры (функции) содержимое регистров ВР, SP, DS и SS должно быть таким же, как и при входе в нее.

С помощью директивы INLINE можно также задавать последовательность машинных кодов, которую необходимо несколько раз вставить в программу. Для этого используется описание INLINE-процедуры, например:

Procedure DisableInterrupts; 

inline ($FA); {CLI}

INLINE-процедура имеет обычный для Турбо Паскаля заголовок, в то время как тело процедуры пишется целиком с помощью оператора INLINE. Всякий раз, когда в программе будет встречаться оператор вызова INLINE-процедуры, компилятор Турбо Паскаля будет вставлять на это место не код вызова процедуры, а нужные машинные коды. Например, вместо вызова процедуры в операторе

DisableInterrupt;

компилятор вставит команду запрета прерываний CLI. Таким образом, INLINE-процедуры служат своеобразным средством расширения возможностей стандартного компилятора Турбо Паскаля и подобны макросам ассемблера. Использование INLINE-процедур увеличивает скорость исполнения программы, так как не осуществляется генерация (и исполнение) команд передачи управления в процедуру. По этой причине в INLINE-процедурах не следует использовать команды выхода из подпрограммы. INLINЕ-процедура может иметь параметры, однако на них нельзя ссылаться в INLINE-директивах (на другие символы Турбо Паскаля ссьшаться можно). В следующем примере перемножаются два числа типа INTEGER, результат имеет тип LONGINT:

FUNCTION LongMul(X,YInteger) : Longint;

inline ( 

$5 А/ {POP AX; получить в АХ число Х }

$58/ { POP DX; получить в DX число Y } 

$F7/$EA); { IMUL DX; DX:AX ;= X * Y }

Отметим, что в силу упоминавшегося сходства с макросами ассемблера, имена INLINE-подпрограмм не могут использоваться в качестве аргументов в операторах @ или служить параметрами функций ADDR, OFS и SEG.




Содержание  Назад  Вперед