41. Модели памяти. Директива определения модели памяти. Упрощенные директивы сегментации.

Для простых программ, содержащих по одному сегменту для кода, данных и стека, хотелось бы упростить ее описание. Для этого были придуманы упрощенные директивы сегментации. И возникла потребность управлять размещением сегментов и функциях директивы ASSUME. Была придумана директива MODEL.Эта директива связывает сегменты, которые в случае использования упрощенных директив сегментации имеют предопределенные имена, с сегментными регистрами.

Синтаксис директивы MODEL

Различные модификаторы модели: NEARSTACK, FARSTACK, USE16, USE32, DOS, OS2
Единственным обязательным параметром директивы MODEL является модель памяти. Этот параметр определяет набор сегментов программы, размеры сегментов данных и кода, способ связывания сегментов и сегментных регистров.
Стандартные значения параметра модель памяти директивы MODEL.



Модели памяти
Модель Тип кода Тип данных Назначение модели
TINY Near Near Весь код и все данные комбинируются в одну группу с именем DGROUP. Эта модель используется для программ, ассемблируемых в формате .COM.
SMALL Near Near Код представляет собой один сегмент. Все данные комбинируются в группу с именем DGROUP. (обычно используется)
MEDIUM Far Near Для кода используется несколько сегментов, по одному на модуль. Данные находятся в группе с именем DGROUP.
COMPACT Near Far Код находится в одном сегменте. Все ближние данные находятся в группе с именем DGROUP. Для ссылки на данные используются дальние указатели.
LARGE Far Far Для кода используется несколько сегментов, по одному на модуль. Все ближние данные находятся в группе с именем DGROUP. Для ссылки на данные используются дальние указатели.
HUGE Far Far То же, что модель LARGE
FLAT Near Near То же, что и модель SMALL, но имеет более широкое использование (Win32 единственная модель)

В некоторых компиляторах может быть не DGROUP, а FLAT.
В случае, если необходимо создание различных (отличных от стандартных – DGROUP — сегментов), то можно задать имя кодового сегмента самостоятельно.



«Язык» и “модификатор_языка” вместе определяют порядок передачи параметров при вызове процедуры, соглашения о присвоению имен общедоступным процедурам и идентификаторам (которые использует компоновщик), а также правила освобождения стека от параметров.

Модификаторы языка: C, Basic, FORTRAN, Pascal, CPP, SYSCALL, STDCALL, PROLOG, NOLANGUAGE.

STDCALL
При вызове процедуры с помощью INVOKE аргументы в стек помещаются в обратном порядке.
Параметры переданные через стек должны удаляться внутри процедуры с помощью RET n
Общедоступные имена процедур при экспортировании заменяются на _имя@m, где m – некоторое число, обозначающее количество байт, которые занимают параметры в стеке, округленное до большего кратного 4 или 2.
C(CPP)
При вызове процедуры с помощью INVOKE аргументы в стек помещаются в обратном порядке.
Параметры переданные через стек должны удаляться в вызывающей программе (при помощи директив управления стеком)
Общедоступные имена процедур на _имя@
Pascal
При вызове процедуры с помощью INVOKE аргументы в стек помещаются в прямом порядке.
Параметры переданные через стек должны удаляться внутри процедуры с помощью RET n
Общедоступные имена процедур ИМЯ

Как писалось выше, директива model позволяет использовать в программах на ассемблере упрощенные директивы сегментации. Вот они:



Упрощенные директивы сегментации
Директива Описание
.STACK [размер] Начало или продолжение сегмента стека модуля. Необязательный параметр [размер] задает размер стека. По умолчанию стек имеет размер 1КБ.
.CONST Начало или продолжение сегмента постоянных данных (констант) модуля. Постоянные данные всегда являются ближними (NEAR) и эквивалентны инициализированным данным.
.DATA .Начало или продолжение сегмента инициализированных данных. Используется для определения данных типа NEAR
.DATA? Начало или продолжение сегмента неинициализированных данных типа NEAR
.FARDATA [имя] Начало или продолжение сегмента инициализированных данных типа FAR
.FARDATA? [имя] Начало или продолжение сегмента неинициализированных данных типа FAR
.CODE [имя] Начало или продолжение сегмента кода

P.S. Наличие в некоторых директивах параметра [имя]говорит о том, что возможно определение нескольких сегментов этого типа.

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

При использовании директивы MODEL транслятор делает доступными несколько идентификаторов, к которым можно обращаться во время работы программы, с тем, чтобы получить информацию о тех или иных характеристиках данной модели памяти: @code, @data, @fardata, @fardata?, @curseg, @stack.

Пример программы с использованием упрощенных директив сегментации:
.MODEL USE32 FLAT                  ;описываем модель памяти
.386
.STACK                             ;инициализируем сегмент стека
.CONST                             ;инициализируем константы
	Bits_In_Byte eq 8
	Bits_In_Word = 16
.DATA                              ;инициализируем сегмент данных
	msgdb “sample msg.”, ‘$’   ;сообщение для вывода
.CODE                              ;инициализируем сегмент кода
	mov ax, @data              ;помещаем в ax адрес сегмента данных
	mov ds, ax   
	mov cl, Bits_In_Byte       ;cl = 8
	lea bx, msg                ;загружаем в bx адрес нашего сообщения
	mov ax, 4C00h              ;помещаем в ax номер функции вывода
	int 21h                    ;вызываем прерывание
END
17.07.2015