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

Сегментирование текстов программ

В примере Б.2 директивы .stack, .Data, .code указывают начало соответствующего сегмента, директива Ends при этом не нужна. Признаком конца текущего сегмента является начало следующего или директива END, завершающая текст программы, поэтому вложение сегментов исключено. В тексте программы, кроме указанных сегментов, могут использоваться другие, описанные обычным способом.

Перед специальными директивами имена сегментов не указываются, но они могут понадобиться для использования в программе. Макроассемблер присваивает стековому сегменту имя stack, сегменту данных – имя _data (нижняя черта обязательна). Имя сегмента кодов зависит от модели памяти, например, при моделях small и compact оно будет _text. Присвоенные сегментам имена можно посмотреть в карте памяти, которую формирует компоновщик при указании файла с типом тар (см. выше).

Для управления последовательностью расположения сегментов в примере Б.2 использована директива Dosseg, которая размещает сегменты в соответствии с соглашениями DOS. Это значит, что первым в теле задачи будет расположен кодовый, а последним – стековый сегмент. Если сегментов всего три, то данные будут размещены после кодов, перед областью стека. Дополнительные сегменты располагаются между кодами и данными.

Работа с именами сегментов

Макроассемблер рассматривает имя сегмента как константу (а не как переменную), ее прямая пересылка в сегментный регистр невозможна, поэтому приходится использовать регистр-посредник. Например, в большинстве случаев в начале выполнения задачи надо определить содержимое сегментного регистра DS, поместив в него код сегмента данных. Это можно сделать с помощью двух следующих команд:

start: mov ax, data; ax = код сегмента данных mov ds, ax; ds = ax

Этот пример составлен исходя из предположения, что сегмент данных описан так, как приведено в примере Б.1. Если же он описан, как в примере Б.2, то в первой команде надо изменить имя data на _data или @data.

Макроассемблер позволяет определить код сегмента тремя разными способами: указать его явно в виде числа, указать имя сегмента или указать имя метки, расположенной в нужном сегменте. В последнем случае перед именем метки помещается оператор seg. Следующие три команды иллюстрируют сказанное:

mov ax, 0400h; указание конкретного числового значения
mov ax, job; явное указание имени сегмента
mov ax, seg buf; косвенная ссылка на сегмент по имени метки

Команды первого типа нужны при обращении к сегментам, расположенным вне тела программы, например к области данных BIOS.

Команды второго типа применяются при работе с сегментами, описанными в тексте программы. Точное значение таких сегментов заранее неизвестно, его вычисляет DOS при загрузке программы в память для выполнения.

Команды третьего типа полезны в тех случаях, когда метка является внешним именем, не описанным в программе, и нужно узнать, какому сегменту она принадлежит.

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

Резервирование пространства памяти

Большинство графических задач нуждается в определенном пространстве ОЗУ для размещения буферов различного назначения. В простейшем случае для резервирования требуемого пространства памяти в текст программы включаются дополнительные сегменты.

Это можно сделать, например, так:

Job Segment; начало сегмента
buffer db 65536 dup (?); директива резервирует 65536 байтов
Job Ends; конец сегмента

В приведенном примере сегмент становится частью тела задачи и увеличивает его размер на соответствующее количество байтов. Поэтому такой способ распределения пространства ОЗУ является вспомогательным и применять его можно только в порядке исключения.

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

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