Иллюстрированный самоучитель по Турбо Паскалю
Другие возхможности Турбо Паскаля
- Внешние
процедуры(функции)
- Использование встроенных машинных
кодов
- Обращение к функциям операционной
системы
- Поддержка процедур обработки
прерываний
- Запуск
внешних программ
- Оверлей
- Прямое обращение
к памяти и портам ввода-вывода
- Длинные строки
Внешние процедуры (функции)
С помощью внешних процедур (функций) можно осуществить вызов из программы
процедур или функций, написанных на языке ассемблера. Ассемблер обеспечивает
компиляцию программ, написанных на машинно-ориентированном языке
программирования низкого уровня. В Турбо Паскале есть собственный встроенный
ассемблер см. гл.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.