12.4. Использование оператора или директивы INLINE
Для коротких подпрограмм (до десятка операторов) можно использовать непосредственное задание всей подпрограммы или ее части в кодах процессора, используя оператор или директиву inline. Отличие оператора от директивы заключается в том, что оператор может быть использован в подпрограмме совместно с другими операторами, написанными на языках Паскаль или ассемблера, а директива предполагает, что подпрограмма целиком состоит лишь из нее одной.
Само написание оператора или использование директивы inline практически ничем не отличается друг от друга. Каждый из них начинается с зарезервированного слова inline, за которым в круглых скобках через прямой слэш (/) записываются байты или слова кодов команд. При этом каждый элемент будет либо байтом, либо словом в зависимости от фактического значения (байт, если значение в пределах 0..255, слово - в остальных случаях). Этот стандартный размер можно изменить, используя указатель размера < или >. Если используется указатель размера <, информация размещается в одном байте, причем, если ее размер больше одного байта, используется только младший байт. Указатель размера > всегда размещает информацию в одном 16-разрядном слове (см. пример ниже). В качестве элементов оператора или директивы inline можно использовать идентификаторы языка Паскаль (в директиве нельзя только использовать идентификаторы передаваемых в подпрограмму параметров).
Пример. Программа, использующая подпрограмму-функцию, определяющую максимальный элемент из массива целых чисел, написанную на языке ассемблера и использующую оператор inline.
program EXAMPLE24;
const
N = 7; {Размер массива}
Massiv: array[l..n] of Integer = (1, 2, 3, 2, 17, 7, 2); {Исходный массив}
function Max (var Mas; N : Integer) : Integer;
begin
inline(
$C5/$76/6/ {LDS SI,Mas}
$B8/>$0/ {MOV AX,0}
$BB/$8001/ {MOV BX,8001h}
$8B/$4E/4/ {MOV CX,N}
$3B/$C8/ {CMP CX,AX}
$7E/$09/ {JLE @@3}
$AD/ {@@l: LODSW}
$3B/$C3/ {CMP AX,BX}
$7E/$02/ {JLE @@2}
$8B/$D8/ {MOV BX,AX}
$E2/$F7); {@@2: L00P@@1}
asm
MOV AX,BX {@@3: MOV AX,BX)
end
end;
begin
WriteLn('Максимальное число массива равно: ',Max(Massiv, N));
ReadLn
end.
Несколько иначе используется директива inline. При использовании этой директивы подпрограмма представляет собой макроопределение ассемблера, и при обращении к ней ее коды помещаются в место обращения. В этом случае не формируются команды обращения к подпрограмме и выхода из нее. Если подпрограмме передаются параметры, они, как обычно, передаются через стек, из которого их можно взять. Такой вариант используется для очень коротких подпрограмм и дает наиболее эффективный результат. В качестве примера рассмотрим все ту же задачу поиска в массиве максимального числа, хотя используемая здесь подпрограмма и несколько великовата для данного варианта.
Пример. Программа, использующая подпрограмму-функцию, определяющую максимальный элемент из массива целых чисел, написанную на языке ассемблера и использующую директиву inline.
program EXAMPLE25;
const
N = 7; {Размер массива}
Massiv: array[l..n] of Integer = (1, 2, 3, 2, 17, 7, 2); {Исходный массив}
function Max (var Mas; N : Integer) : Integer;
inline(
$59/ {POP CX число элементов}
$5E/ {POP SI смещение массива}
$1F/ {POP DS адрес сегмента}
$33/$C0/ {XOR AX, AX}
$BB/$8001/ {MOV BX, 8001h}
$3B/$C8/ {CMP CX, AX}
$7E/$09/ {JLE @@3}
$AD/ {@@1: LODSW}
$3B/$C3/ {CMP AX, BX}
$7E/$02/ {JLE @@2}
$8B/$D8/ {MOV BX, AX}
$E2/$F7/ {@@2: LOOP @@1}
$8B/$C3) ;
begin
WriteLn('Максимальное число массива равно: ',Max(Massiv, N));
ReadLn
end.
|