Лекция

доцента кафедры ИВТ Гродненского госуниверситета

канд. техн. наук  Ливак Елены Николаевны

 

директивы сегментации.

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

 

В лекции:

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

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

Упрощенные директивы определения сегмента

Структура программы на языке 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   [<модификатор>] <модель памяти> [др. параметры]

                                                       

Обязательным параметром директивы 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