|
Другие возхможности Турбо Паскаля
- Внешние процедуры(функции)
- Использование встроенных машинных
кодов
- Обращение к функциям операционной
системы
- Поддержка процедур обработки прерываний
- Запуск внешних программ
- Оверлей
- Прямое обращение к памяти и портам
ввода-вывода
- Длинные строки
Внешние процедуры (функции)
С помощью внешних процедур (функций)
можно осуществить вызов из программы процедур или функций,
написанных на языке ассемблера. Ассемблер обеспечивает
компиляцию программ, написанных на машинно-ориентированном
языке программирования низкого уровня. В Турбо Паскале
есть собственный встроенный ассемблер см. гл.12). В
этом разделе речь идет о программах, написанных и откомпилированных
с помощью внешнего ассемблера, такого как, например,
ассемблер фирмы MicroSoft или Turbo Assembler фирмы
Borland.
Машинно-ориентированный язык ассемблера
предоставляет квалифицированному программисту богатейшие
возможности использования всех особенностей архитектуры
ПК. Ассемблерные программы выполняются значительно быстрее
и занимают меньший объем памяти, чем программы, написанные
на Турбо Паскале, однако низкий уровень языка ассемблера
существенно снижает производительность труда программиста
и резко усложняет отладку программ. Как правило, на
языке ассемблера пишутся сравнительно небольшие фрагменты
программ, в которых используются недоступные из Турбо
Паскаля особенности архитектуры ПК.
Внешняя процедура (функция) в программе,
написанной на Турбо Паскале, объявляется своим заголовком,
за которым следует стандартная директива EXTERNAL, например:
Function LoCase (ch : char):char; external;
Procedure Swapping (var a,b; N:word);
external;
Как видно из этих примеров, тело внешней
процедуры (функции) отсутствует - его заменяет директива
EXTERNAL. Для подключения ассемблерной программы необходимо
предварительно ее откомпилировать и получить объектный
файл с расширением OBJ, содержащий перемещаемый код
ассемблерной программы. Непосредственно перед описанием
внешней процедуры (функции) в тело основной программы
вставляется директива компилятора {$L<имя файла>},
где <имя фата> - имя OBJ-файла. Диск и каталог,
в котором следует искать этот файл, если он не обнаружен
в текущем каталоге, указываются опцией OPTIONS/DIRECTORIES/OBJECT
DIRECTORIES (см.прил.1).
Перед передачей управления внешней процедуре
(функции) программа помещает параметры обращения в программный
стек в том порядке, как они перечислены в заголовке
процедуры (функции). Ассемблерная процедура должна сохранить
регистры ВР, SP, SS и DS центрального процессора в самом
начале своей работы и восстановить содержимое этих регистров
перед возвратом управления в программу. Остальные регистры
можно не сохранять и соответственно не восстанавливать.
Параметры могут передаваться по ссылке
или по значению. Если параметр передается по ссылке,
в стек помещается указатель, содержащий абсолютный адрес
параметра, если по значению - в стек помещается сам
параметр, точнее - его значение. Все параметры-переменные,
т.е. параметры, объявленные в заголовке с предшествующим
словом VAR, всегда передаются по ссылке. Параметры-значения
могут передаваться по ссылке или по значению в зависимости
от длины внутреннего представления соответствующего
параметра. В общем случае используется следующее правило:
если длина внутреннего представления параметра-значения
составляет 1, 2 или 4 байта, он передается своим значением,
т.е. его значение помещается в стек. Точно так же через
стек передаются и все вещественные данные длиной в 4,
6, 8 и 10 байт (в версии 4.0 эти данные передаются через
стек сопроцессора 8087/80287, начиная с версии 5.0 -через
стек центрального процессора 8086/80486). Во всех остальных
случаях, если длина внутреннего представления больше
4 байт, соответствующий параметр передается по ссылке.
Ассемблерные функции в зависимости от
длины внутреннего представления результата должны возвращать
его через регистры центрального процессора или сопроцессора
по следующим правилам:
- длиной в 1 байт - в регистре AL;
- длиной в 2 байта - в регистре АХ;
- длиной в 4 байта - в регистрах DX:AX
(старшее слово в DX);
- тип REAL (6 байт) - в регистрах DX:BX:AX;
- типы SINGLE, DOUBLE, EXTENDED и СОМР
- через стек сопроцессора 8087/80486;
- указатели - в регистрах DX:AX (сегмент
в DX);
- строки возвращаются по ссылке: адрес
начала строки помещается в DX:AX (сегмент в DX).
Все ассемблерные процедуры должны размещаться
в сегменте с именем CODE или CSEG, или с именем, оканчивающимся
на _ТЕХТ; инициализированные локальные Переменные помещаются
в сегмент с именем CONST или с именем, оканчивающимся
на _DATA. Все другие локальные переменные необходимо
размещать в сегменте с именем DATA или DSEG, или с именем,
оканчивающимся на _BSS. Любые другие объявления сегментов
игнорируются. Все имена, объявленные в интерфейсной
части модулей программы, написанной на Турбо Паскале,
становятся доступны ассемблерной процедуре (функции)
после их объявления директивой EXTRN. Точно так же все
имена ассемблерных процедур и функций, которые должны
быть доступны программе на Турбо Паскале, следует объявлять
директивой PUBLIC.
|