Оформление программных модулей
Подключение исходного модуля
Расположенные в теле задачи модули не являются общедоступными. Поэтому после отладки дополнительный сегмент с описанием подпрограмм удаляется из текста программы и помещается в отдельный файл. Имя, тип и расположение файла на жестком или гибком диске вы можете выбирать по своему усмотрению.
Для включения содержимого файла в нужном месте текста программы указывается специальная директива:
INCLUDE спецификация_файла
Спецификация должна быть настолько подробной, чтобы Макроассемблер мог найти и прочитать файл. Очень часто эта директива применяется для подключения файлов, содержащих тексты макроопределений. Обычно в установочный комплект MASM включено несколько таких файлов, они могут располагаться в специальном каталоге INCLUDE.
В данном случае нас интересуют файлы, содержащие исходные тексты общедоступных подпрограмм. На состав и назначение подпрограмм не налагается никаких специальных ограничений, должны лишь соблюдаться общие правила оформления программных сегментов, а именно.
- каждый сегмент имеет уникальное имя;
- размер кода после компиляции не превышает 65 536 байтов;
- в тексте отсутствуют ошибки, т. е. он должен быть предварительно отлажен.
Таким образом, содержимое включаемого файла становится частью текста программы и компилируется Макроассемблером. Если в задании на компиляцию указан файл листинга, то, просмотрев его, вы увидите полный результат компиляции, в том числе и включенного файла.
Пример объектного модуля
Для получения объектного модуля надо внести изменения в подключаемый модуль и откомпилировать его отдельно от основной задачи.
Изменения заключаются в том, что в начале текста модуля добавлены две директивы:
- EXTERN – для описания используемых внешних имен;
- PUBLIC – для объявления подпрограмм модуля общедоступными.
Кроме этого, нужен признак конца текста модуля, которым является директива END. В примере В.3 показано, что изменится в модуле примера В.2.
Пример В.З. Исходный текст для получения объектного модуля.
; Сюда надо вставить макроопределения из примера 2.12 subr SEGMENT word public 'subr'; начало сегмента EXTERN GrUnit:word, Cur win:word, VMC:dword PUBLIC NxtWin, SetWin, PrevWin ASSUME cs:subr; установка соответствия ;.386; тип микропроцессора ; Далее располагается текст примера В.1, содержащий ; описание подпрограмм NxtWin, SetWin и PrevWin subr ENDS; конец сегмента END; конец текста модуля
Текст примера В.3 начинается с комментария, напоминающего о том, что перед описанием сегмента надо расположить макроопределения PushReg и PopReg. Они используются в подпрограмме SetWIN для сохранения в стеке и последующего восстановления содержимого регистров ах, bx и dx (см. пример В.1). Можно отказаться от их включения, заменив первый макровызов тремя командами push, а второй тремя командами pop. Раньше мы об этом не говорили, поскольку модуль предназначался для совместной компиляции с текстом программы, в котором описаны указанные макроопределения.
В директиве EXTERN перечислены имена переменных GrUnit, cur_win и VMC, которые описаны в сегменте данных основной программы. Назначение и способ определения значений этих переменных подробно обсуждались в Главе 2, а их описание показано в примере 2.11 той же главы.
Следующая директива PUBLIC объявляет имена подпрограмм Nxtwin, setwin и PrevWIN общедоступными.
Обратите внимание на то, что в директиве ASSUME описан только кодовый сегмент, а если вы работаете с MASM 6.0 или более поздней версией, то эту директиву можно вообще исключить.