Директиви сегмантаціі в асемблері

Директиви сегмантаціі в асемблері

Кожна програма містить 3 типи сегментів:

Функціональне призначення сегмента трохи ширше, ніж просте розбиття програми на блоки коду, даних і стека. Сегментація є частиною більш загального механізму, пов'язаного з концепцією модульного програмування. Вона передбачає уніфікацію оформлення об'єктних модулів, що створюються компілятором, в тому числі з різних мов програмування. Це дозволяє об'єднувати програми, написані на різних мовах. Саме для реалізації різних варіантів такого об'єднання і призначені директиви сегментації.

Спрощені директиви сегментації

Для завдання сегментів в тексті програми можна користуватися спрощеними директивами:

  • .CODE - для вказівки початку сегмента коду;
  • .DATA - для вказівки початку сегмента даних;
  • .STACK - для вказівки початку сегмента стека.

Однак використання спрощених директив сегментації не дозволяє створити більш трьох сегментів для однієї програми.

Стандартні директиви сегментації

Поряд зі спрощеними директивами сегментації може також використовуватися стандартна директива SEGMENT. яка визначає початок будь-якого сегменту. синтаксис:

ІмяСегмента SEGMENT align combine dim 'class'
.
ІмяСегмента ENDS

Директива ENDS визначає кінець сегмента.

Атрибут вирівнювання сегмента (тип вирівнювання) align повідомляє компонувальнику про те, що потрібно забезпечити розміщення початку сегмента на заданій кордоні. Це важливо, оскільки при правильному вирівнюванні доступ до даних в процесорах, сумісних з базовим i8086, виконується швидше. Допустимі значення цього атрибута наступні:

За замовчуванням тип вирівнювання має значення PARA.
Атрибут комбінування сегментів (комбінаторний тип) combine повідомляє компонувальнику, як потрібно комбінувати сегменти різних модулів, що мають одне і те ж ім'я. За замовчуванням атрибут комбінування приймає значення PRIVATE. Значеннями атрибута комбінування сегмента можуть бути:

Атрибут класу сегмента (тип класу) 'class' - це укладена в лапки рядок, яка допомагає компонувальнику визначити відповідний порядок проходження сегментів при складанні програми з сегментів декількох модулів. Компоновщик об'єднує разом в пам'яті всі сегменти з одним і тим же ім'ям класу (ім'я класу, в загальному випадку, може бути будь-яким, але краще, якщо воно буде відображати функціональне призначення сегмента). Типовим прикладом використання імені класу є об'єднання в групу всіх сегментів коду програми (зазвичай для цього використовується клас 'code'). За допомогою механізму типізації класу можна групувати також сегменти ініціалізованих і неініціалізованих даних.

Всі сегменти самі по собі рівноправні, так як директиви SEGMENT і ENDS не містять інформації про функціональне призначення сегментів. Для того щоб використовувати їх як сегменти коду, даних або стека, необхідно попередньо повідомити транслятора про це, для чого використовують спеціальну директиву ASSUME. Ця директива повідомляє транслятор про те, який сегмент до якому сегментному регістру прив'язаний. У свою чергу, це дозволить транслятору коректно пов'язувати символічні імена, певні в сегментах. Прив'язка сегментів до сегментних регістрів здійснюється за допомогою операндів цієї директиви, в яких ІмяСегмента має бути ім'ям сегмента, певним в початковому тексті програми директивою SEGMENT або ключовим словом nothing. Якщо в якості операнда використовується тільки ключове слово nothing. то попередні призначення сегментних регістрів анулюються, причому відразу для всіх шести сегментних регістрів. Але ключове слово nothing можна використовувати замість аргументу ІмяСегмента. в цьому випадку буде вибірково розриватися зв'язок між сегментом з ім'ям ІмяСегмента і відповідним сегментним регістром.
Директива SEGMENT може застосовуватися з будь-якою моделлю пам'яті. При використанні директиви SEGMENT з моделлю flat потрібно вказати транслятору, що все сегментні регістри встановлюються відповідно до моделі пам'яті flat. Це можна зробити за допомогою директиви ASSUME:

ASSUME CS. FLAT. DS: FLAT. SS. FLAT. ES. FLAT. FS. ERROR. GS. ERROR

Регістри FS і GS програмами не використовуються, тому для них вказується атрибут ERROR.