- •1. Предварительные сведения 6
- •2. Процессоры intel в реальном режиме 11
- •3. Директивы и операторы ассемблера 51
- •Введение
- •1. Предварительные сведения
- •1.1. Подготовка программ на языке ассемблера
- •1.2. Представление данных в компьютерах
- •1.2.1. Двоичная система счисления
- •1.2.2. Биты, байты и слова
- •1.2.3. Шестнадцатеричная система счисления
- •1.2.4. Числа со знаком
- •1.2.5. Логические операции
- •1.2.6. Коды символов
- •2. Процессоры intel в реальном режиме
- •2.1. Регистры процессора
- •2.1.1. Регистры общего назначения
- •2.1.2. Модели памяти и сегментные регистры
- •2.1.3. Стек
- •2.1.4. Регистр флагов
- •2.2.4. Косвенная адресация
- •2.2.5. Адресация по базе со смещением
- •2.2.6. Косвенная адресация с масштабированием
- •2.2.7. Адресация по базе с индексированием
- •2.2.8. Адресация по базе с индексированием и масштабированием
- •2.3. Основные непривилегированные команды
- •2.3.1. Пересылка данных
- •2.3.2. Двоичная арифметика
- •2.3.3. Десятичная арифметика
- •2.3.4. Логические операции
- •2.3.5. Сдвиговые операции
- •2.3.6. Операции над битами и байтами
- •2.3.7. Команды передачи управления
- •2.3.8. Строковые операции
- •2.3.9. Управление флагами
- •2.3.10. Загрузка сегментных регистров
- •2.3.11. Другие команды
- •3. Директивы и операторы ассемблера
- •3.1. Структура программы
- •3.2. Директивы распределения памяти
- •3.2.1. Псевдокоманды определения переменных
- •3.2.2. Структуры
- •3.3. Организация программы
- •3.3.1. Сегменты
- •3.3.2. Модели памяти и упрощенные директивы определения сегментов
- •3.3.4. Процедуры
- •3.3.5. Конец программы
- •3.3.6. Директивы задания набора допустимых команд
- •3.3.7. Директивы управления программным счетчиком
- •3.3.8. Глобальные объявления
- •3.3.9. Условное ассемблирование
- •3.4. Выражения
- •3.5. Макроопределения
- •3.5.1. Блоки повторений
- •3.5.2. Макрооператоры
- •3.5.3. Другие директивы, используемые в макроопределениях
- •3.6. Другие директивы
- •3.6.1. Управление файлами
- •3.6.2. Управление листингом
- •3.6.3. Комментарии
- •Литература
3.3.2. Модели памяти и упрощенные директивы определения сегментов
Модели памяти задаются директивой .MODEL
.model модель, язык, модификатор
где модель — одно из следующих слов:
TINY — код, данные и стек размещаются в одном и том же ceгменте размером до 64 Кб. Эта модель памяти чаще всего используется при написании на ассемблере небольших программ.
SMALL — код размещается в одном сегменте, а данные и стек — в другом (для их описания могут использоваться разные сегменты, но объединенные в одну группу). Эту модель памяти также удобно использовать для создания программ на ассемблере.
COMPACT — код размещается в одном сегменте, а для хранения данных могут использоваться несколько сегментов, так что для обращения к данным требуется указывать сегмент и смещение (данные дальнего типа).
MEDIUM — код размещается в нескольких сегментах, а все данные — в одном, так что для доступа к данным используется только смещение, а вызовы подпрограмм используют команды дальнего вызова процедуры.
LARGE и HUGE — и код, и данные могут занимать несколько сегментов.
FLAT — то же, что и TINY, но используются 32-битные сегменты, так что максимальный размер сегмента, содержащего и данные, и код, и стек, — 4 мегабайта.
Язык — необязательный операнд, принимающий значения С, PASCAL, BASIC, FORTRAN, SYSCALL и STDCALL. Если он указан, ассемблер считает, что все процедуры рассчитаны на вызов из программ на соответствующем языке высокого уровня, так что, например, если указан язык С, все имена ассемблерных процедур, объявленных как PUBLIC, будут изменены так, чтобы начинаться с символа подчеркивания, как это принято в С.
Модификатор — необязательный операнд, принимающий значения NEARSTACK (по умолчанию) или FARSTACK. Во втором случае сегмент стека не будет объединяться в одну группу с сегментами данных.
После того как модель памяти определена, вступают в силу упрощенные директивы определения сегментов, объединяющие действия директив SEGMENT и ASSUME. Кроме того, сегменты, объявленные упрощенными директивами, не требуется закрывать директивой ENDS — они закрываются автоматически, как только ассемблер обнаруживает новую директиву определения сегмента или конец программы.
Директива .CODE описывает основной сегмент кода. Описание
.code имя_сегмента
эквивалентно
_TEXT segment word public ‘CODE’
для моделей TINY, SMALL и COMPACT и
name_TEXT segment word public 'CODE'
для моделей MEDIUM, HUGE и LARGE (name — имя модуля, в котором описан данный сегмент). В этих моделях директива .CODE также допускает необязательный операнд — имя определяемого сегмента, но все сегменты кода, описанные так в одном и том же модуле, объединяются в один сегмент с именем NAME_TEXT.
.stack размер
Директива .STACK описывает сегмент стека и эквивалентна директиве
STACK segment para public ‘STACK’
Необязательный параметр указывает размер стека. По умолчанию он равен 1 килобайту.
.data
Описывает обычный сегмент данных и соответствует директиве
_DATA segment word public ‘DATA’
.data?
Описывает сегмент неинициализированных данных:
_BSS segment word public ‘BSS’
Этот сегмент обычно не включается в программу, а располагается в памяти сразу после ее конца, так что все описанные в нем переменные на момент загрузки программы имеют неопределенные значения.
.const
Описывает сегмент неизменяемых данных:
CONST segment word public 'CONST'
В некоторых операционных системах этот сегмент будет загружен так, что попытка записи в него может привести к ошибке.
.fardata имя_сегмента
Сегмент дальних данных:
имя_сегмента segment para private 'FAR_DATA’
Доступ к данным, описанным в этом сегменте, потребует загрузки сегментного регистра. Если не указан операнд, в качестве имени сегмента используется FAR_DATA.
.fardata? имя_сегмента
Сегмент дальних неинициализированных данных:
имя_сегмента segment para private 'FAR_BSS’
Так же как и в случае FARDATA, доступ к данным из этого сегмента потребует загрузки сегментного регистра. Если имя сегмента не указано, используется FAR_BSS.
Во всех моделях памяти сегменты, описанные директивами .DATA, .DATA?, .CONST, .FARDATA и .FARDATA?, а также сегмент, описанный директивой .STACK, если при описании модели не был указан модификатор FARSTACK, и сегмент .CODE в модели TINY автоматически объединяются в группу с именем FLAT — для модели памяти FLAT или DGROUP — для всех остальных моделей. При этом сегментный регистр DS (и SS, если не было FARSTACK, и CS в модели TINY) настраивается на всю эту группу, как если бы была выполнена команда ASSUME.