Иллюстрированный самоучитель по SVGA

Оформление программных модулей

Общедоступные подпрограммы могут располагаться в исходных или в объектных модулях. Исходный модуль состоит из программного сегмента, содержащего описание одной или нескольких подпрограмм на языке Макроассемблера. Объектный модуль получается в результате обработки исходного модуля компоновщиком. Исходные модули могут располагаться непосредственно в тексте основной программы или храниться в отдельных файлах, в последнем случае они являются общедоступными. Объектные модули могут храниться в виде отдельных файлов, имеющих тип obj, или в библиотечных файлах, имеющих тип lib. Они подключаются к задаче только в процессе ее компоновки (сборки). В данном разделе описаны рекомендации, которых следует придерживаться при оформлении обоих типов модулей.

Пример модуля в теле задачи

На первой стадии подготовки исходного модуля производится составление, набор текста и отладка подпрограмм, поэтому модуль удобнее включить в текст основной программы в виде отдельного сегмента, а не хранить в отдельном файле. В примере В.2 показан вариант оформления дополнительного сегмента в основной программе.

Пример В.2. Сегмент с описанием подпрограмм NxtWin, SetWin, PrevWin.

subr SEGMENT word public 'subr1; начало сегмента
ASSUME cs:subr, ds:@data; установка соответствия;.386; тип микропроцессора
; Далее располагается текст примера В.1, содержащий
; описание подпрограмм NxtWin, SetWin и PrevWin subr ENDS; конец сегмента

Первая директива примера В.2 открывает описание сегмента. В данном случае его параметры можно было не указывать, они приведены просто для иллюстрации. Параметр word обозначает, что сегмент располагается в памяти, начиная с четного адреса. Параметр public является признаком общедоступного сегмента. Заключенное в кавычки название сегмента передается компоновщику и становится общедоступным.

Замечание
Обратите внимание на то, что между параметрами директивы SEGMENT отсутствуют запятые!

Директива ASSUME нужна для того, чтобы Макроассемблер мог определить, что будет находиться в сегментных регистрах cs и ds при выполнении подпрограмм. Без этого невозможна компиляция команд. С регистром cs всегда связывается имя сегмента, в котором расположена директива ASSUME. С регистром ds связывается имя сегмента данных, который описан вне данного модуля. Имя, с которым ассоциируется ds, зависит от способа описания сегмента данных в основном тексте программы. В примере В.2 предполагается, что сегмент данных был описан с помощью специальной директивы .data (см. Приложение Б).

Если вы забудете указать директиву ASSUME, то при компиляции Макроассемблер может выдавать аварийные сообщения, смысл которых заключается в том, что не определен один из сегментных регистров. Чтобы лучше понять назначение директивы, уберите ее из текста и посмотрите, что из этого получится. В частности, результат зависит от версии MASM.

В примере В.2 строка, содержащая третью директиву, начинается с символа "точка с запятой". Подпрограммы Nxtwin, setwin и Prevwin составлены с использованием набора команд микропроцессора Intel 8086, поэтому в данном случае директива.386 не нужна. Однако большинство описанных в книге примеров рассчитано на возможности микропроцессора Intel 80386, и для их компиляции данная директива необходима.

Разрядность сегмента

При обработке директив описания сегментов Макроассемблер проверяет установленный тип микропроцессора и выбирает соответствующий режим выполнения команд, расположенных в сегменте (реальный или защищенный). По умолчанию установлен 16-разрядный (реальный) режим выполнения команд и набор инструкций для микропроцессора Intel 8086.

Если директива 0.386 предшествует описанию сегмента, то он будет объявлен как 32-разрядный, расположенные в нем команды будут рассчитаны на работу с 32-разрядными адресами. В реальном режиме результаты выполнения таких команд непредсказуемы.

Поэтому при создании программ или подпрограмм, предназначенных для выполнения в реальном режиме работы микропроцессора, директиву.386 надо располагать после описания сегмента. В таком случае она оказывает влияние только на набор инструкций микропроцессора.

Начиная с версии 6.0, Макроассемблер поддерживает директивы.486 и.586, разрешающие использование новых инструкций микропроцессоров Intel 486 и Pentium. Кроме того, появилась возможность выбора разрядности сегментов по умолчанию или ее явного описания с помощью ключевых слов USE16 И USE32.

В конце файла, формируемого Макроассемблером, приводится описание всех сегментов программного модуля. При компиляции обязательно укажите имя файла и затем проверьте, соответствуют ли указанная в нем разрядность сегментов той, которую вы предполагаете.

Расположение сегмента в тексте программы зависит от версии MASM, который вы используете. Если это MASM 6.0 и выше, то дополнительный сегмент может располагаться как перед основным текстом программы (перед сегментом кодов), так и после него. Но если вы работаете с MASM 5.1, то дополнительный сегмент может располагаться только перед сегментом кодов. В противном случае при каждом вызове подпрограмм, расположенных в дополнительном сегменте, MASM 5.1 выводит аварийное сообщение о необходимости предварительного описания подпрограммы.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.