Введение в технологию программирования на языке Ассемблера, страница 7

В общем случае, имеются стандартные директивы, которые позволяют получить полный контроль над размещением в памяти сегментов, используемых программой. При этом указание каждого типа сегмента, при его открытии, должно сопровождаться целым рядом атрибутов. Эти атрибуты должны определять: его выравнивание (с какого адреса может начинаться сегмент: с любого адреса, с четного адреса, с адреса кратного 4, 16 или 256); тип комбинирования сегмента; его разрядность; класс и др.  Необходимо, также обязательно указывать конец данного сегмента.

 Для достаточно простых программ, использующих по одному сегменту для кода, данных и стека, что характерно для большинства разрабатываемых ассемблерных программ, используются так называемые упрощенные директивы сегментации. В этом случае, перед заданием сегментов, следует указать специальную директиву указания модели памяти – model. Эта директива связывает сегменты, которые в этом случае  имеют предопределенные имена с сегментными регистрами, и позволяет существенно упростить оформление ассемблерных программ. Например, сегменты, объявленные упрощенными директивами, не требуется заканчивать (закрывать) директивой ends, как это требуется при стандартном задании сегментов. Они закрываются автоматически, как только Ассемблер обнаруживает новую директиву определения сегмента или конец программы. Описание сегментов, при этом, открываются директивами: .code, .dataи .stack. Точки перед именем директив как раз указывают на принадлежность их к упрощенным директивам сегментов.

Ассемблеры рассматриваемого класса используются для создания исполняемых программ при работе с различными процессорами семейства Х86 и совместимых с ними а, следовательно, и с отличающимися наборами команд. Кроме того, они применяются для транслирования программ как в случае использования 16 разрядных, так и в случае использования 32 разрядных адресных смещений в сегментах.

Поэтому в следующей строке ассемблерной программы обычно задается директива, определяющая тип процессора, для которого пишется программа. По умолчанию Ассемблеры используют набор команд базового процессора 8086 с 16 разрядными операндами и смещениями в сегментах. В системе команд каждой последующей модели процессора семейства Х86, к базовой системе  команд добавлялись новые команды, и это должно быть указано в программе соответствующей директивой задания набора допустимых команд. Например, для того, чтобы можно было ассемблировать все команды процессора 80486, необходимо привести директиву  .486р. Для возможности ассемблирования всех команд процессоров 6-го поколения семейства Х86 (до Pentium III), необходимо задать директиву .686р, и т.п.

Если присутствует директива .386 и выше, Ассемблеры всегда определяют все сегменты как 32-разрядные, при условии, что не указан явно операнд директивы модели памяти use16. При этом для Ассемблеров MASM и TASM директиву задания допустимых команд целесообразно указывать в строке перед строкой с директивой model. Например:

                ; название программы

                    MASM

                    .386p

                    model small use16

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

 Аргументами директивы model являются шесть моделей памяти.

 - Tiny- программы, данные и стек располагаются в одном и том же сегменте размером до 64 Кбайт.

 - Small - программы располагаются в отдельном сегменте, а данные и стек в другом, общем.

- Compact - программы располагаются в отдельном сегменте, а для хранения данных могут использоваться несколько сегментов.

- Medium - программы располагаются в нескольких сегментах, а все данные – в одном.

- Large - и программы и данные могут занимать по несколько сегментов.

- Flatмодель,аналогичная Tiny, при 32-битном сегменте размером 4Гбайт.

Наиболее употребляемыми являются модель tinyи модельsmall.

                                             Модель памятиtiny.

Модель памяти tiny используется для создания исполняемых программ формата «com», когда код, данные и стек объединены в одном сегменте. Поэтому эти программы не могут быть по объему больше 64 Кбайт с учетом и стековой области памяти, что вполне достаточно для очень большого количества разрабатываемых процедур, особенно резидентных. В то же время, при этом, доступ к переменным, переходы в программе и вызовы функций, т.е. все адресации в программе, выполняются только с использованием смещения, без необходимости указания начальных адресов сегментов, что упрощает программу и сокращает время ее выполнения. Надо только учитывать, что при использовании модели памяти tinyобязательно надо с помощью директивы orgзадавать начальный адрес размещения программы в сегменте (обычно с операндом 100h), т.е. указать начало размещения получаемого com–файла. Дело в том, что при загрузке com-файла в память, операционная система DOS занимает первые 256 байт (100h) специальным блоком данных PSP (префикс программного сегмента) и должна располагать код программы только после этого блока.

Пример программы с использованием модели памяти типа tiny.

; Progr1.asm

; Выводит на экран сообщение «Hello Comrade!” и завершается.

                    masm

.model         tiny              ; Модель памяти при COM-файлах.

.code                                ; Начало сегмента кода.

org               100h            ; Начальное значение счетчика – 100h.

message       db                ‘Hello Comrade’, 0dh, 0ah, ‘$’ ; строка вывода.

main:           mov             ah, 9             ; Номер функции DOS → в AH.

                    mov             dx, offset message           ; Адрес строки → в DX.

                    int                21h              ; Вызов системной функции DOS.

                    ret                                    ; Завершение COM-программы.

                    end              main            ; Конец программы.                                            

Здесь: 0dh, 0ah и $ – управляющие символы ASCII: 0dh – возврат каретки,

0ah перевод строки и $ - окончание строки.