Расширенное применение директивы сегментации

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

 

<имя сегмента> SEGMENT [выравнивание>] [<объединение>]

['<класс>'][<размер сегмента>]

 

Любой из параметров может отсутствовать, но если они заданы, то должны быть перечислены в указанном порядке и разделены пробелами.

Параметр "класс" указывает в одиночных кавычках имя класса, к которому относится сегмент. Компоновщик объединяет вместе в памяти все сегменты с одним и тем же именем класса. Все сег­менты, для которых класс не указан, считаются относящимися к одному и тому же классу с «пустым» именем.

Параметр "объединение" задает способ комбинирования сегментов различных модулей, имеющих одинаковое имя. Значениями атрибута могут быть PRIVATE, PUBLIC, STACK, AT или COMMON (по умолчанию PRIVATE).

Значение PRIVATE указывает, что сегмент не будет объединяться ни с какими другими сегментами с тем же именем вне данного модуля.

Значение PUBLIC дает указание объединять в один сегмент такие сегменты из любых модулей, у которых одно и то же имя и которые относятся к одному и тому же классу. Объединение нескольких сегментов означает, что сегменты будут расположены в памяти рядом, и смещения всех имен из этих сегментов будут отсчитываться от начала объединенного сегмента. Это позволит один раз установить сегментный регистр на начало общего сегмента и далее, не меняя значение регистра, использовать его для доступа ко всем именам общего сегмента.

Значение STACK дает указание объединять одноименные сегменты, и вычисляет адреса в сегментах относительно регистра SS. Объединенный сегмент рассматривается как сегмент стека и на него перед выполнением программы будут установлены регистры SS и SP (на сегмент типа PUBLIC никакие регистры автоматически не устанавливаются). Если имеется несколько таких сегментов, то SS:SP устанавливаются на тот из них, который был обнаружен компоновщиком последним.

Значение AT <константное выражение> позволяет расположить сегмент по абсолютному адресу параграфа, заданному константным выражением. Все метки и адреса в сегменте отсчитываются относительно вычисленного адреса. С помощью АТ-сегментов обычно вводятся обозначения для фиксированных участков оперативной памяти (векторов прерываний, видеопамяти).

Значение COMMON указывает, что все сегменты с одним и тем же именем и принадлежащие одному и тому же классу должны быть размещены в памяти с одного и того же адреса (с адреса, по которому был размещен первый из таких сегментов), накладывая их содержимое друг на друга. Результирующий сегмент будет иметь длину наибольшего из сегментов. COMMON-сегменты используются, когда одни и те же ячейки памяти желательно именовать по-разному в разных модулях.

Параметр "выравнивание" определяет способ выравнивания по заданной границе, т.е. указывает, с адреса какой крат­ности должен располагаться сегмент (табл. 5.76) (по умолчанию PARA). При правильном выравнивании доступ к данным выполняется быстрее.

 

Табл. 76. Значения параметра выравнивания.

Атрибут Описание
BYTE Выравнивание не выполняется, т.е. сегмент может начинаться с любого адреса памяти.
WORD Сегмент начинается по адресу, кратному двум, т.е. последний (младший) значащий бит физического адреса равен 0 (выравнивание по границе слова).
DWORD Сегмент начинается по адресу, кратному четырем, т.е. два последних (младших) значащих бита равны 0 (выравнивание по границе двойного слова).
PARA Сегмент начинается по адресу, кратному 16, т.е. последняя шестнадцатеричная цифра адреса должна быть 0h (выравнивание по границе параграфа).
PAGE Сегмент начинается по адресу, кратному 256, т.е. две последние шестнадцатеричные цифры должны быть 00h (выравнивание по границе 256-байтной страницы).
MEMPAGE Сегмент начинается по адресу, кратному 4 Кбайт, т.е. три последние шестнадцатеричные цифры должны быть 000h (адрес следующей 4-Кбайтной страницы памяти).

 

 

Параметр "размер сегмента". Для микропроцессоров 386 и выше сегменты могут быть 16 или 32-разрядными: USE16 определяет 16-разрядную адресацию, USE32 – 32-разрядную адресацию.