Информатика на пять О нас
 Добавить в избранное
5byte.ru
 Теория
 8 класс
 9 класс
 10 класс
 11 класс
Задания
 8 класс
 9 класс
 10 класс
 11 класс
Книги
Тесты
ЕГЭ
Turbo Pascal 7
 Описание
 Задачи
HTML
Рефераты

10.5. Директивы подпрограмм

Директивы дают дополнительную информацию транслятору о размещении подпрограмм.

10.5.1. Директива FORWARD

Если одна подпрограмма использует другую, а та, в свою очередь, эту первую, то возникает проблема размещения этих подпрограмм в программе (ни одну из них нельзя поместить перед другой). Чтобы устранить это противоречие,, используется директива forward, позволяющая как бы разбить на две части одну из подпрограмм.

При использовании директивы forward сначала записывается полный заголовок первой подпрограммы. Тело этой подпрограммы заменяется директиве forward. Затем полностью описывается вторая подпрограмма, а уже после это полностью описывается первая подпрограмма. При этом можно записать сокращенный заголовок подпрограммы, который включает слово procedure ил function и ее имя. Список формальных параметров и тип подпрограммы (если это подпрограмма-функция) не указывается.

Пример. Процедура First вызывает процедуру Second, а та, в свою очередь, процедуру First.

procedure First(A, В: Integer); forward; {заголовок первой процедуры}
procedure Second(C: Real); {вторая процедура}
var X, Y: Integer  
begin  
  . . .  
  FirstCX, Y);  
  . . .
end;
procedure First; {первая процедура}
var Z: Real  
begin  
  . . .  
  Second(Z);  
  . . .  
end;  

Директиву forward можно использовать и просто для более удобного размещения подпрограмм: сначала описать все заголовки, а затем - сами подпрограммы. Эту директиву не следует использовать в модулях (см. п. 16) для подпрограмм, объявленных в интерфейсе модуля.

10.5.2. Директивы FAR и NEAR

Как правило, компилятор Turbo Pascal автоматически выбирает адресацию к подпрограмме. Например, если подпрограмма находится в одном файле с основной программой, то она компилируется с "ближним" (near) адресом входа и возврата, состоящим только из смещения в текущем сегменте, а если она находится и модуле, то формируется "дальний" (far) адрес, состоящий из адреса сегмента и смещения.

В некоторых случаях нужен нестандартный вариант компиляции. Так, например, если подпрограмма используется для переменных процедурного типа, она независимо от своего расположения должна компилироваться с получением "дальнего" адреса. В этом случае в подпрограмме можно использовать директиву far, которая сообщит компилятору, что нужно формировать именно такой адрес. Эта директива эквивалентна ключу компилятора {$F+}, однако в отличие от этого ключа действие директивы распространяется только на одну подпрограмму.

Реже используется директива near, которая сообщает компилятору, что подпрограмму следует компилировать с получением именно такого адреса. Эта директива эквивалентна ключу компилятора {$F-}, который выбирается по умолчанию. Действие директивы распространяется только на одну подпрограмму.

10.5.3. Директива EXTERNAL

Директива external позволяет использовать в программе подпрограммы, написанные на языке ассемблера и скомпилированные отдельно. Эти подпрограммы должны быть скомпонованы с основной программой, используя ключ {$L <имя файла>}. Здесь имя файла - имя того файла (с расширением .OBJ), в котором находятся скомпилированные объектные модули подпрограмм, написанных на языке ассемблера.

Пример.

function Max(X, Y: Real): Real; external;
procedure Search(var Mas; N: Integer;
                var Max, Min: Integer); external;
{$L ASMBL.OBJ}

Директиву external следует использовать, если подпрограммы на ассемблере имеют большой размер и их лучше скомпилировать отдельно, а не использовать встроенный ассемблер или писать их в кодах процессора, используя директиву inline (см. п. 10.5.5).

10.5.4. Директива ASSEMBLER

Директива assembler позволяет написать подпрограмму полностью на языке ассемблера. При этом во время компиляции подпрограмма будет автоматически скомпилирована встроенным ассемблером пакета Turbo Pascal. При отладке такой подпрограммы можно использовать встроенный отладчик пакета.

Пример. Функция, определяющая максимальное из двух чисел.

function MaxTwo(X, Y: Integer): Integer; assembler;
asm
    MOV AX , X
    CMP AX , Y
    JG @1
    MOV AX , Y
@1:
end;

10.5.5. Директива INLINE

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

Машинные коды в процедуре записываются в круглых скобках побайтно через прямой слэш (/).

Пример. Функция, вычисляющая максимальное из двух чисел.

function MaxTwo(X, У: Integer): Integer;
inline(
   $58/    { POP AX - получение Y из стека }
   $5A/    { POP DX - получение Х из стека }
   $3B/$C2/      { CMP AX,DX }
   $7F/$02/      { JG - переход через одну команду }
   $8В/$С2);      { MOV AX,DX }

В связи с тем, что такие подпрограммы являются макроопределениями и помещаются всюду, где осуществляется их вызов, нет необходимости организовывать стандартный вход в подпрограмму и выход из нее с сохранением и восстановлением регистров. По этой причине такие подпрограммы являются довольно эффективными по быстродействию и объему занимаемой памяти. Однако использовать их целесообразно лишь в случаях, когда они являются достаточно короткими (не более десятка команд).

10.5.6. Директива INTERRUPT

Директива interrupt предназначена для процедур, обрабатывающих прерывания. Такие процедуры имеют стандартный заголовок:

procedure IntHandler(Flags, CS, IP, AX,
                     BX, CX, DX, SI, DI, DS, ES, BP: Word); interrupt;
begin
. . .
end;

В заголовке отдельные параметры можно опускать (но только с начала списка), промежуточные параметры удалять нельзя, например:

procedure IntHandler(DI, ES, BP: Word); interrupt;
       {неправильный заголовок}
procedure IntHandler(DI, DS, ES, BP: Word); interrupt;
       {правильный заголовок}

Нельзя в заголовке процедуры обработки прерываний записывать и какие-либо другие параметры.





 У Вас есть материал пишите нам
 
    Copyright © 2008    
Rambler's Top100