- •Глава 3. Директивы и операторы ассемблера
- •3.1. Структура программы
- •3.2. Директивы распределения памяти
- •3.2.1. Псевдокоманды определения переменных
- •3.2. Директивы распределения памяти
- •3.2.1. Псевдокоманды определения переменных
- •3.2.2. Структуры
- •3.3. Организация программы
- •3.3.1. Сегменты
- •3.2. Директивы распределения памяти
- •3.2.1. Псевдокоманды определения переменных
- •3.2.2. Структуры
- •3.3. Организация программы
- •3.3.1. Сегменты
- •3.3.2. Модели памяти и упрощенные директивы определения сегментов
- •3.3.3. Порядок загрузки сегментов
- •3.3.4. Процедуры
- •3.3.5. Конец программы
- •3.3.6. Директивы задания набора допустимых команд
- •3.3.7. Директивы управления программным счетчиком
- •3.3.8. Глобальные объявления
- •3.3.9. Условное ассемблирование
- •3.4. Выражения
- •3.5. Макроопределения
- •3.6. Другие директивы
- •3.6.1. Управление файлами
- •4. Основы программирования для ms-dos
- •4.1. Программа типа сом
- •4.2. Программа типа ехе
- •4.3. Вывод на экран в текстовом режиме
- •4.3.1. Средства dos
- •4.4. Ввод с клавиатуры
- •4.4.1. Средства dos
- •4.5. Графические видеорежимы
- •4.5.1. Работа с vga-режимами
- •4.6. Работа с мышью
- •4.7. Другие устройства
- •4.7.1. Системный таймер
- •4.8. Работа с файлами
- •4.9. Управление памятью
- •4.9.1. Обычная память
- •4.10. Загрузка и выполнение программ
- •4.11. Командные параметры и переменные среды
3.3.3. Порядок загрузки сегментов
Обычно сегменты загружаются в память в том порядке, в котором они описываются в тексте программы, причем, если несколько сегментов объединяются в один, порядок определяется по началу первого из объединяемых сегментов. Этот порядок можно изменить с помощью одной из специальных директив.
.alpha
Эта директива устанавливает алфавитный порядок загрузки сегментов.
.dosseg ; для MASM и WASM
или
dosseg ; для MASM и TASM
Устанавливает порядок загрузки сегментов, существующий в MS DOS и часто требуемый для взаимодействия программ на ассемблере с программами на языках высокого уровня. DOSSEG устанавливает следующий порядок загрузки сегментов:
1. Все сегменты класса 'CODE'.
2. Все сегменты, не принадлежащие группе DGROUP и классу 'CODE'.
3. Группа сегментов DGROUP:
3.1. Все сегменты класса 'BEGDATA'.
3.2. Все сегменты, кроме классов 'BEGDATA', 'BSS' и 'STACK'.
3.3. Все сегменты класса 'BSS'.
3.4. Все сегменты класса 'STACK'.
.seq
Устанавливает загрузку сегментов в том порядке, в котором они описаны в тексте программы. Этот режим устанавливается по умолчанию, так что директива .SEQ просто отменяет действие .ALPHA или .DOSSEG.
Знание порядка загрузки сегментов необходимо, например, для вычисления длины программы или адреса ее конца. Для этого надо знать, какой сегмент будет загружен последним, и смещение последнего байта в нем.
3.3.4. Процедуры
Процедуройв ассемблере является все то, что в других языках называют подпрограммами, функциями, процедурами и т.д. Ассемблер не накладывает на процедуры никаких ограничений — на любой адрес программы можно передать управление командой CALL, и оно вернется к вызвавшей процедуре, как только встретится команда RET. Такая свобода выражения легко может приводить к трудночитаемым программам, и в язык ассемблера были включены директивы логического оформления процедур.
метка proc язык тип USES регистры ; TASM
или
метка proc тип язык USES регистры ; MASM/WASM
...
ret
метка endp
Все операнды PROC необязательны.
Типможет принимать значения NEAR и FAR, и если он указан, все команды RET в теле процедуры будут заменены соответственно на RETN и RETF. По умолчанию подразумевается, что процедура имеет тип NEAR в моделях памяти TINY, SMALL и COMPACT.
Операнд языкдействует аналогично такому же операнду директивы .MODEL, определяя взаимодействие процедуры с языками высокого уровня. В некоторых ассемблерах директива PROC позволяет также считать параметры, передаваемые вызывающей программой. В этом случае указание языка необходимо, так как различные языки высокого уровня используют разные способы передачи параметров.
USES— список регистров, значения которых изменяет процедура. Ассемблер помещает в начало процедуры набор команд PUSH, а перед командой RET — набор команд POP, так что значения перечисленных регистров будут восстановлены.
3.3.5. Конец программы
end start_label
Этой директивой завершается любая программа на ассемблере. В роли необязательного операнда здесь выступает метка (или выражение), определяющая адрес, с которого начинается выполнение программы. Если программа состоит из нескольких модулей, только один файл может содержать начальный адрес, так же как в C только один файл может содержать функцию main().