Лекция
доцента кафедры ИВТ Гродненского госуниверситета
канд. техн. наук Ливак Елены Николаевны
директивы сегментации.
Упрощенные директивы сегментации
В лекции:
Сегменты и директивы сегментации
Упрощенные директивы определения сегмента
Структура программы на языке Assembler
Программа на языке Assembler в соответствии с особенностями архитектуры компьютера (микропроцессора) состоит из сегментов.
Вспомним, что физически сегмент представляет собой область (блок) памяти, занятую командами и/или данными.
Адреса сегментов (адрес начала сегмента) хранятся в соответствующих сегментных регистрах.
Адреса команд/данных вычисляются относительно начала сегмента.
Микропроцессор имеет шесть сегментных регистров, посредством которых может одновременно работать:
- с одним сегментом кода (CS);
- с одним сегментом стека (SS);
- с одним сегментом данных (DS);
- с тремя дополнительными сегментами данных (ES,FS, GS).
Итак, исходный текст программы на языке Assembler разбивается на сегменты. Каждая программа содержит как минимум сегмент данных, сегмент стека, сегмент кода.
Для описания сегментов предназначены директивы сегментации.
Директивы сегментации подразделяются на
1) стандартные (поддерживаются всеми трансляторами Assembler);
2) упрощенные (поддерживаются транслятором TASM).
Стандартно сегменты на языке Assembler описываются с помощью директивы SEGMENT.
Синтаксическое описание сегмента представляет собой следующую конструкцию
<имя сегмента> SEGMENT [тип выравнивания] [тип комбинирования]
[класс сегмента] [тип размера сегмента]
<тело сегмента>
<имя сегмента> ENDS
Параметры имеют множество значений, которыми при желании можно ознакомиться в справочниках команд.
С помощью директивы ASSUME можно сообщить транслятору, какой сегмент, к какому сегментному регистру «привязан», или, говоря боле точно, в каком сегментном регистре хранится адрес сегмента..
Формат директивы ASSUME:
ASSUME <сегментный регистр>:<имя сегмента>
Директивы SEGMENT и ASSUME - стандартные директивы сегментации.
Для простых программ, которые содержат по одному сегменту кода, данных и стека легче использовать упрощенные описания соответствующих сегментов.
Трансляторы MASM и TASM предоставляют возможность использования упрощенных директив сегментации (вместо SEGMENT).
Замечание. Стандартные и упрощенные директивы сегментации не исключают друг друга.
Совет 1. Стандартные директивы используются, когда программист хочет получить полный контроль над размещением сегментов в памяти и их комбинированием с сегментами других модулей.
Совет 2. Упрощенные директивы целесообразно использовать
1) для простых программ
2) программ, предназначенных для связывания с программными модулями, написанными на языках высокого уровня (это позволяет компоновщику эффективно связывать модули разных языков за счет стандартизации связей и управления).
Упрощенные директивы определения сегмента
(для режима MASM)
.CODE [имя]
Директива предназначена для определения начала или продолжения сегмента кода. Возможно определение нескольких сегментов данного типа.
.DATA
Директива предназначена для определения начала или продолжения сегмента инициализированных данных. Также используется для определения данных типа near.
.STACK [размер]
Директива предназначена для определения начала или продолжения сегмента стека.
Параметр [размер] задает размер стека.
.CONST
Директива предназначена для определения начала или продолжения сегмента постоянных данных (констант).
.DATA?
Директива предназначена для определения начала или продолжения сегмента неинициализированных данных. Также используется для определения данных типа near
.FARDATA [имя]
Директива предназначена для определения начала или продолжения сегмента инициализированных данных типа far. Возможно определение нескольких сегментов данного типа.
.FARDATA? [имя]
Директива предназначена для определения начала или продолжения сегмента неинициализированных данных типа far. Возможно определение нескольких сегментов данного типа.
Для режима IDEAL директивы носят следующие названия (в порядке упоминания)
CODESEG[имя] DATASEG STACK [размер] CONST UDATASEG
FARDATA [имя] UFARDATA [имя]
Совместно с упрощенными директивами сегментации используется директива указания модели памяти MODEL, которая частично управляет размещением сегментов и выполняет функции директивы ASSUME, т.е. связывает сегменты с сегментными регистрами (поэтому при использовании упрощенных директив сегментации директиву ASSUME можно не использовать).
Замечание. Необходимо явно инициализировать только регистр ds.
MODEL [<модификатор>] <модель памяти> [др. параметры]
Обязательным параметром директивы MODEL является «модель памяти». Этот параметр определяет модель сегментации памяти для программного модуля.
Возможные значения параметра «модель памяти»:
TINY - Код и данные объединены в одну группу с именем DGROUP. Используется для создания программ формата com.
SMALL - Код занимает один сегмент, данные объединены в одну группу с именем DGROUP. Эту модель обычно используют для большинства программ на языке Assembler.
MEDIUM - Код занимает несколько сегментов, по одному на каждый объединяемый программный модуль. Все ссылки на передачу управления типа far. Данные объединены в одной группе, все ссылки на них типа near.
COMPACT - Код в одном сегменте; ссылка на данные типа far.
LARGE - Код в нескольких сегментах. Каждый объединяемый в одну программу модуль хранится в отдельном сегменте кода.
Параметр «модификатор» директивы MODEL уточняет особенности использования выбранной модели памяти.
Возможные значения параметра «модификатор модели памяти»:
use16 - сегменты выбранной модели используются как 16-битные
use32 - сегменты выбранной модели используются как 32-битные
dos - программа предназначена для работы в ОС MS-DOS
Другие параметры используются при написании программ на разных языках программирования (пока использовать не будем).
Пример.
Для большинства программ на ассемблере используют директиву
MODEL SMALL
При использовании директивы MODEL транслятор создает и делает доступными для программиста идентификаторы, в которых хранится информация о физических адресах сегментов.
Перечислим идентификаторы, создаваемые директивой MODEL:
@code - физический адрес сегмента кода
@data - физический адрес сегмента данных типа near
@fardata - физический адрес сегмента данных типа far
@fardata? - физический адрес сегмента неинициализированных данных типа far
@curseg - физический адрес сегмента неинициализированных данных типа far
@stack - физический адрес сегмента стека
Структура программы на языке Assembler
Таким образом, общая структура программы может выглядеть следующим образом:
masm ;режим работы TASM: ideal или masm
model small ;модель памяти
.stack <размер> ;сегмент стека
.data ;сегмент данных
<описание данных>
BEGIN : .code ;сегмент кода
<команды>
end BEGIN ;конец программы с точкой входа BEGIN
Пример.
Текст программы с использованием упрощенных директив сегментации.
Описаны 3 сегмента программы: сегмент данных, сегмент стека и сегмент кода.
В сегменте данных задана строка для вывода на экран.
Размер стека равен 256 байт.
Сегмент кода содержит команды начала и завершения программы, а также комментарии к пропущенным командам.
masm ;режим работы TASM: ideal или masm
model small ;модель памяти
.data ;сегмент данных
message db 'Привет всем,$'
.stack ;сегмент стека
db 256 dup ('?') ;сегмент стека
.code ;сегмент кода
main : ;начало программы
mov ax,@data ;заносим в сегментный регистр ds
mov ds,ax ; физический адрес сегмента данных
;здесь будут команды вывода строки на экран
………….
; завершение программы
mov ax,4c00h ;пересылка 4c00h в регистр ax
int 21h ;вызов прерывания с номером 21h
end main ;конец программы с точкой входа main