Модуль Турбо Ассемблера может обращаться к любой процедуре, функции, переменной или типизованной константе Турбо Паскаля, ко- торая описывается на самом внешнем уровне программы или модуля, с которым она компонуется. (Заметим, что это включает в себя пере- менные, описанные после директивы компилятора {$L} и внешние опи- сания, связанные с данным модулем.) Метки и обычные константы Турбо Паскаля языку Ассемблера недоступны.
Примечание: Эти включает в себя переменные, указанные после директивы компилятора $L и описаниях external, свя- занных с данным модулем.
Предположим, в вашем программе Турбо Паскаля описываются следующие глобальные переменные:
var a : byte; b : word; c : shortint; d : integer; e : real; f : single; g : double; h : extended; i : comp; j : pointer;
В программе на языке Ассемблера вы можете получить доступ ко всем этим переменным с помощью описаний EXTRN:
EXTRN A : BYTE ; 1 байт EXTRN B : WORD ; 2 байта EXTRN C : BYTE ; в Ассемблере значения со знаком и ; без знака интерпретируются одинаково EXTRN D : WORD ; то же самое EXTRN E : FWORD ; 6-байтовое действительное значение ; (обрабатывается программно) EXTRN F : DWORD ; 4-байтовое значение с плавающей ; точкой в формате IEEE EXTRN G : QWORD ; 8-байтовое значение с плавающей ; точкой (двойной точности) в ; формате IEEE EXTRN H : TBYTE ; 10-байтовое значение с плавающей ; точкой во временном формате EXTRN I : QWORD ; 8-байтовое целое со знаком в ; формате IEEE (сопроцессор 8087) EXTRN J : DWORD ; указатель Турбо Паскаля
Аналогичным образом можно получить доступ к процедурам и функциям Турбо Паскаля, включая библиотечные. Предположим, у вас имеется модуль Турбо Паскаля, который выглядит следующим образом:
unit Sample; { Пример модуля, в котором определяется нескольку процедур Паскаля, вызываемых из процедуры на языке Ассемблера }
interface
procedure TestSample;
procedure PublicProc; { для обращения извне должна быть дальнего типа } inplementation
var A : word;
procedure AsmProc; external; {$L ASMPROC.OBJ}
procedure PublicProc; begin { PublicProc } Writeln('В PublicProc'); end { PublicProc }
procedure NearProc; { должна быть ближнего типа } begin { NearProc } Writeln('B NearProc'); end; { NearProc }
{$F+} procedure FarProc { должна иметь дальний тип согласно директиве компилятора } begin { FarProc } Writeln('B FarProc'); end { FarProc }
{$F-}
procedure TestSample; begin { TestSample } Writeln('B TestSample'); A := 10; Writeln('Значение A перед ASMPROC = ',A); AsmProc; Writeln('Значение A после ASMPROC = ',A); end { TestSample };
end.
Процедура AsmProc вызывает процедуры PublicProc, NearProc или FarProc, используя директиву EXTRN следующим образом:
DATA SEGMENT WORD PUBLIC ASSUME DS:DATA EXTRN A:WORD ; переменная из модуля DATA ENDS
CODE SEGMENT BYTE PUBLIC ASSUME CS:CODE EXTRN PublicProc : FAR ; дальняя процедура ; (экспортируется модулем) EXTRN NearProc : NEAR ; ближняя процедура ; (локальная для модуля) EXTRN FarProc : FAR ; дальняя процедура ; (локальна, но задана, ; как дальняя) AsmProc PROC NEAR PUBLIC AsmProc CALL FAR PTR PublicProc CALL NearProc CALL FAR PTR FarProc mov cx,ds:A ; взять переменную из ; модуля sub cx,2 ; изменить ее mov ds:A,cx ; записать ее обратно RET AsmProc ENDP CODE ENDS END
Основная программа, которая проверяет эту программу на Ас- семблере и модуль Паскаля, выглядит следующим образом:
program TSample; uses Sample; begin TestSample; end.
Чтобы сформировать пример программы с помощью компилятора, работающего в режиме командной строки, и Ассемблера, используйте следующие команды (или командный файл):
TASM ASMPROC TPC /B SAMPLE TSAMPLE
Так как внешняя подпрограмма должна объявляться в программе Турбо Паскаля на самом внешнем уровне процедур, вы не можете для доступа к объектам, являющимся локальными по отношению к процеду- рам или функциям использовать описания EXTRN. Однако, ваша прог- рамма на Турбо Ассемблере при вызове из программы Турбо Паскаля может получить эти объекты, как значения параметров-переменных.