Особенности использования директивPUBLIC и EXTRN

Borland Pascal может получать доступ только к тем идентификаторам, которые объявлены общедоступными директивойPUBLIC, причем, как уже говорилось, это могут быть не только имена процедур. Таким образом, с точки зрения Borland Pascal, следующие объявления эквивалентны:

AsmLabel PROC FAR

PUBLIC AsmLabel

……

AsmLabel:

PUBLIC AsmLabel

Кроме того, Borland Pascal lie распознает идентификаторов, объявленных как PUBLIC, если они находятся в сегменте данных, поэтому все конструкции, которые должны будут взаимодействовать с Pascal-процедурами, необходимо объявлять в кодовом сегменте.

Применение директивыEXTRN позволяет Turbo Assembler получать доступ к процедурам, функциям, переменным и типизированным константам Borland Pascal, которые объявлены на самом верхнем уровне модуля. Эти правила не распространяются только на метки и обычные константы Borland Pascal, к которым ассемблерные программы не могут обращаться.

Например, если в программе на Borland Pascal объявлены следующие глобальные переменные:

var

а : Byte;

b : Word;

с : Shortint;

d : Integer;

e : Real;

f : Single;

g : Double;

h : Extended;

i : Comp;

j : Pointer;

то для обращения к этим переменным в программе на ассемблере необходимо использовать объявления следующего вида:

EXTRN A: BYTE ;1 байт

EXTRN В: WORD ;2 байта

EXTRN С: BYTE 1 байт

EXTRN D: WORD Целые числа

EXTRN E: FWORD ;шестибайтовые вещественные числа

EXTRN F: DWORD ;четырехбайтовые вещественные числа

EXTRN G: QWORD ;восьмибайтовые вещественные числа

EXTRN H: TBYTE ;десятибайтовые вещественные числа

EXTRN I: QWORD ;восьмибайтовые целые числа со знаком для сопроцессора

EXTRN J: DWORD ;указатель Borland Pascal

Таким же способом можно получить доступ к процедурам и функциям Borland Pascal.

Например, пусть в модуле Sample вызывается ассемблерная процедура AsmProc:

unit Sample interface

procedure TestSample procedure PublicProc; far { должна иметь тип FAR }

implementation

var

A: word;

procedure AsmProc; near; external;

<$L ASMPROC} procedure PublicProc;

begin

Writeln(' Работает PublicProc');

end;

procedure NearProc; near; {должна иметь тип NEAR} begin

WriteInC Работает NearProc'); . end;

procedure FarProc; far; {должна иметь тип FAR} begin

Writeln(' Работает FarProc');

end;

procedure TesfSample;

begin

WriteInC Работает TesfSample');

A:=10;

WriteInC Значение А перед ASMPROC=',A);

AsmProc;

WriteInC Значение А после ASMPROC=',A);

end;

end.

Процедура AsmProc, используя объявление EXTRN, получает доступ к процедурам PublicProc, NearProc или FarProc модуля Sample:

DATA SEGMENT WORD PUBLIC ASSUME DS:DATA EXTRN A:WORD DATA ENDS

EXTRN PublicProc : FAR EXTRN FarProc : FAR

CODE SEGMENT BYTE PUBLIC ASSUME CS:CODE

EXTRN NearProc : NEAR

AsmProc PROC NEAR

PUBLIC AsmProc

call PublicProc

call NearProc

call FarProc

mov cx,ds:A

sub ex,2

mov ds:A

ret AsmProc ENDP

CODE ENDS END

Главная программа, использующая модуль на Pascal и ассемблерный код, имеет следующий вид:

program TSample;

uses Sample;

begin

TestSample;

end.

Существует несколько ограничений для применения директивыEXTRN.Во-первых, точка, применяемая в Borland Pascal для разделения имен различных объектов, имеет в ассемблере иной смысл, поэтому объявления типа

EXTRN SYSTEM.Assign : FAR

будут вызывать ошибку при трансляции.

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

EXTRN PublicProc : FAR,

то оператор вида

call PublicProc +42

является недопустимым.

В-третьих, компоновщик Borland Pascal не распознает операторы, которые работают с отдельными байтами переменных размером в слово. Например, при объявлении

EXTRN i : WORD

в ассемблерной программе нельзя использовать выражения LOW i и HIGH i.

19.1.3. Использование привязки сегментов

Выполняемые файлы, генерируемые компилятором Borland Pascal, могут загружаться и любое доступное адресное пространство оперативной памяти. Поскольку при создании программы сегменты, в которые она будет загружаться, неизвестны, то компоновщик оставляет всю работу по привязке сегментных ссылок загрузчику программ MS DOS. При загрузке программы на выполнение происходит привязка всех ссылок на сегменты к конкретным адресам, после которой все ссылки к сегментам (типаCODE и DATA) содержат правильные значения.

Программы, разрабатываемые с помощью Turbo Assembler, могут использовать .чту возможность для выполнения адресации сегментов во время выполнения. Например, если в программе необходимо изменить значение регистра DS без выполнения обращения к стеку или использования временной переменной, то это можно выполнить с помощью оператораSEG:

mov ax, SEG DATA mov ds.ax

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

Эта техника также должна использоваться подпрограммами обработки прерываний для сохранения информации в сегменте глобальных данных Pascal программы, так как во время возникновения прерывания регистр OS может и не содержать адрес этого сегмента, с помощью которого осуществляется доступ к переменным и типизированным константам.

19.1.4. Игнорирование неиспользуемого кода

Одной из характерных особенностей Borland Pascal является игнорирование неиспользуемого кода. Это означает, что в выполняемый файл не помещается код тех процедур, для которых при компиляции программы не было ни одного вызова. Для ассемблерных модулей действие этого правила несколько ослаблено, так как Borland Pascal не получает о них полной информации.

В случае применения объектных файлов Borland Pascal будет игнорировать их код, только если в результирующей программе не выполняется вызов ни одной из процедур, находящихся в данном модуле. Если же хотя бы к одной из процедур имеется ссылка, то весь объектный файл помещается в выполняемый файл.

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