14.7.1. Оператор inline
Несмотря на то, что средствами Турбо Паскаля можно сделать практически все, не всегда полученный результат будет максимально
- 305 -
эффективным по быстродействию, если сравнивать с грамотно написанной программой на ассемблере. Другой вопрос, за сколько дней и ночей будет написан и отлажен ассемблерный текст, а за сколько — программы на Турбо Паскале. Все это верно и для других языков. В последних версиях языка Си можно просто писать вставки на ассемблере посреди текста Си-программ. Довольно похожим способом решена проблема включения машинных команд в текст программ на Турбо Паскале. Правда, в текущих версиях языка для того надо употреблять не мнемонические команды языка ассемблера, а их аналоги в машинном коде. Оператор вставки машинного кода записывается с помощью зарезервированного слова inline и списка кодов, разделенных косой чертой:
inline ( Код1/ Код2/ Код3/ .../ КодN );
Встретив такой оператор, компилятор прекращает на время генерировать код и вставляет Код1, Код2 и другие из оператора inline без каких-либо особых преобразований, а затем снова начинает преобразовывать предложения Турбо Паскаля в выполнимый код. Это более гибкий способ, чем компоновка объектного файла директивой {$L ИмяФайла}, поскольку позволяет вставлять в программу «чисто ассемблерные» отдельные операторы, в то время как {$L...} позволяет лишь использовать внешние процедуры и функции. Программирование в чистых машинных кодах, как это требует формат inline, — занятие не для начинающих. Не имея большого опыта работы с ассемблерами для процессоров семейства 8086/286, лучше избегать применения оператора inline, тем более, что необходимость в нем возникает не так уж часто. В книге Дж.Дунтемана [5], посвященной подобным вопросам, приводится такой список задач, требующих прямого использования машинных кодов:
1. Процедуры обработки прерываний.
2. Резидентные программы.
3. Организация многозадачных режимов.
Дж. Дунтеман характеризует эти задачи как задачи «не для малодушных», особенно третью. Код в операторе inline — это либо константа, либо имя переменной. Константа должна быть целым положительным числом типа Byte или Word и может быть записана как в десятичном, так и в шестнадцатеричном формате. Пример: оператор
inline( $CD / 05 ); { Мнемоника -> INT 05H }
это то же самое, что вызов прерывания 05 (печать с экрана). Если значение константы попадает в диапазон 0...255, то она хранится
- 306 -
как однобайтовый код. Если же оно превосходит 255, то хранится как слово (два байта). В последнем случае код хранится по машинному правилу: младший байт (Lo( Word )) предшествует старшему (Hi( Word )). Можно явно заказывать формат хранения кода, используя перед константой знаки «<» и «>». Если константа записана с предшествующим знаком «<», то от нее будет взят только младший байт. Но если ей предшествует знак «>», то она будет записана в двух байтах, например:
inline( >1 ) даст два байта кода: $01 и $00.
Размер хранения кодов важен для организации переходов внутри оператора inline.
Если вместо константы стоит имя переменной, то оно трактуется как слово (два байта) — смещение в сегменте хранения этой переменной. Таким образом, переменная в inline задает адрес в сегменте DS (DSeg) или SS (SSeg) первого байта своего значения. Если же нужен не первый байт значения, а, например, третий, то можно указать это, дописав к переменной константу — смещение от ее первого байта, например:
inline(.../ XVar+2 /...);
Адрес первого байта XVar может быть записан как XVar+0. Смещение от начала переменной может быть и отрицательным, достаточно заменить знак «+» на «-».
Внутри кодов inline могут быть доступны значения глобальных переменных и типизированных констант (они хранятся в сегменте DS), а также, если inline стоит внутри тела процедуры или функции, становятся доступными локальные переменные этих процедур и их переменные параметры. Подробное изложение техники обращения к ним, соглашений о размещении и размерах локальных переменных, способах передачи значений в процедуры, функции и обратно заняло бы слишком много места (не считая таблицы машинных кодов для 8088/86/286). Подробно вопросы интерфейса с ассемблерными программами и работа с inline рассматривается в гл. 15 справочного руководства по Турбо Паскалю 5.0 [2] и в уже упоминавшейся книге [5] (с оговорками, ибо она написана для версии 3.0). Здесь же мы дадим один последний совет начинающим любителям машинных кодов: во избежание фатальных последствий запрещено модифицировать кодами оператора inline регистры процессора ВР, SP, SS и DS. Остальные — можно.
- 307 -