Сегментирование текстов программ
Составленные на языке Макроассемблера программы обязательно сегментируются. В простейшем случае вся программа может состоять только из одного сегмента. Подобная программа была приведена в примере 4.1.
Описание и расположение сегментов. В большинстве случаев текст программы состоит, по крайней мере, из трех сегментов, содержащих область стека, раздел данных и коды. В примере Б.1 показана общая структура программы, содержащей три основных сегмента.
Пример Б.1. Структура программы, состоящей из трех сегментов.
stack Segment word stack "stack"; начало стекового сегмента db 10Oh dup (?); размер области стека 10Oh байтов stack Ends; конец стекового сегмента. data Segment; начало сегмента данных ; в этом сегменте располагается описание используемых в программе данных data Ends: конец сегмента данных code Segment; начало кодового сегмента ; в этом сегменте располагается текст основной ; программы и входящих в нее подпрограмм code Ends; конец кодового сегмента END; конец текста программы
Из текста примера Б.1 видно, что описание сегмента открывает директива Segment, а закрывает Ends. Перед обеими директивами указывается одинаковая метка, символ "двоеточие" в данном случае отсутствует. Метка указывается дважды для того, чтобы при работе с вложенными сегментами Макроассемблер мог определить, какой из них закрывает данная директива. Формально вложенные сегменты допустимы, но особых преимуществ их использование не дает.
После директивы segment могут располагаться параметры, которые обычно не нужны. Исключением является стековый сегмент, если не указать параметр stack, то компоновщик (link.exe) выдаст сообщение об его отсутствии в теле задачи. Это не аварийное, а предупреждающее сообщение, т. к. стековый сегмент действительно может отсутствовать. Однако если он явно описан, а компоновщик его не обнаружил, значит, в тексте программы допущена ошибка, и ее надо исправить.
Последовательность расположения сегментов в тексте программы не имеет значения ни для Макроассемблера, ни для компоновщика, ни для DOS. Поэтому разработчик располагает их в нужном ему порядке, а основным критерием является наглядность текста программы и удобство его анализа. Правда в некоторых случаях бывает важно знать, какой сегмент расположен последним в тексте построенной задачи. Такой случай будет рассмотрен в следующем разделе.
Расположение сегментов в задаче
Макроассемблер может располагать сегменты в тексте будущей задачи либо в порядке их описания в исходной программе, либо по именам в алфавитном порядке. Вариант расположения можно выбрать с помощью директив .SEQ и .ALPHA (в обоих случаях указание точки обязательно), которые располагаются перед описанием первого сегмента. Директива .SEQ устанавливает расположение сегментов в порядке их описания, а директива .ALPHA – в алфавитном порядке. Обычно по умолчанию сегменты располагаются в порядке их описания.
Реальное расположение сегментов в построенной задаче компоновщик выводит в файл, имя которого надо указать в ответ на подсказку "List file >", по умолчанию такой файл имеет тип тар. Если в ответ на подсказку вы введете конкретное имя, то получите файл, содержащий имена, адреса и размеры описанных в программе сегментов.
Специальные директивы описания сегментов
В документации на Макроассемблер для описания сегментов, содержащих константы, данные, коды и стек, рекомендуется использовать специальные директивы: .CONST, .DATA, .CODE, .STACK (указание точки обязательно), которые автоматически формируют все параметры сегмента. Им обязательно должна предшествовать директива .MODEL с указанием названия используемой модели памяти (пример Б.2). Допустимо использование следующих имен: small, compact, medium, large и huge.
Перечисленные типы моделей памяти поддерживают компиляторы таких языков программирования, как Паскаль, Си, Фортран и некоторые другие, что и объясняет введение директивы .MODEL. В MASM 6.0 специально для защищенного режима введена еще одна модель – flat.
Пример Б.2. Специальные директивы описания основных сегментов.
Dosseg; задает расположение сегментов .Model small; описание модели памяти .Stack 100h; описание стекового сегмента .Data; начало сегмента данных ; В этом сегменте располагается описание ; используемых в программе данных Code; начало сегмента кодов ; В этом сегменте располагается текст основной ; программы и входящих в нее подпрограмм END; конец текста программы