"Модель_памяти" и "модификатор_модели" определяют модель сегментации памяти, используемую в программе. В применяемых в Турбо Ассемблере стандартных моделях можно использовать специальные сегменты для: - кода; - инициализированных данных; - неинициализированных данных; - инициализированных данных дальнего типа; - неинициализированных данных дальнего типа; - констант; - стека.Сегмент кода содержит обычно код модуля (но при необходимос- ти может также содержать данные). Специальные модели памяти задают, как можно ссылаться на эти сегменты с помощью сегментных регистров, и как они объединяются в группы (если это имеет место). При написании программы вы должны хранить эти сегменты отдельно, независимо от размера программы. Затем для объединения сегментов в группы вы можете выбрать соот- ветствующую модель. Если вы храните эти сегменты раздельно, и ва- ша программа увеличивается в размере, вы можете использовать большую модель. Единственным обязательным параметром директивы MODEL являет- ся модель памяти. Каждая стандартная модель памяти описывается в Таблице 7.1. Поле "модификатор_модели" позволяет вам изменить отдельные аспекты модели. Вы можете задавать при необходимости несколько модификаторов модели. Доступные модификаторы модели приведены в Таблице 7.2. Заметим, что в целях совместимости с MASM 5.2 вы можете за- давать спецификатор модели в двух местах. Если вы не используете спецификатор модели, Турбо Ассемблер подразумевает спецификатор NEARSTACK и USE32 (при выборе процессоров 80386 или 80486). Если не задано обратное, то основой считается DOS. В больших моделях кода для переопределения используемого по умолчанию имени сегмента кода используется необязательное поле "имя_сегмента_кода". Обычно это имя модуля с присоединенным к нему именем _TEXT. Стандартные модели памяти Таблица 7.1 ----------T---------T--------T--------------T------------------- ¦Модель ¦ Код ¦Данные ¦Предполагаемые¦Описание ¦ ¦ ¦ ¦ ¦регистры ¦ ¦ +---------+---------+--------+--------------+-------------------+ ¦TINY ¦ ближний ¦ближний ¦cs=dgroup ¦Весь код и все дан-¦ ¦ ¦ ¦ ¦ds=ss=dgroup ¦ные комбинируются¦ ¦ ¦ ¦ ¦ ¦в одну группу с¦ ¦ ¦ ¦ ¦ ¦именем DGROUP. Эта¦ ¦ ¦ ¦ ¦ ¦модель используется¦ ¦ ¦ ¦ ¦ ¦для программ, ас-¦ ¦ ¦ ¦ ¦ ¦семблируемых в фор-¦ ¦ ¦ ¦ ¦ ¦мат.COM. Некоторые¦ ¦ ¦ ¦ ¦ ¦языки эту модель не¦ ¦ ¦ ¦ ¦ ¦поддерживают. ¦ ¦ ¦ ¦ ¦ ¦ ¦ +---------+---------+--------+--------------+-------------------+ ¦SMALL ¦ ближний ¦ближний ¦cs=_text ¦Код представляет¦ ¦ ¦ ¦ ¦ds=ss=dgroup ¦собой один сегмент.¦ ¦ ¦ ¦ ¦ ¦Все данные комбини-¦ ¦ ¦ ¦ ¦ ¦руются в группу с¦ ¦ ¦ ¦ ¦ ¦именем DGROUP. Это¦ ¦ ¦ ¦ ¦ ¦наиболее общая мо-¦ ¦ ¦ ¦ ¦ ¦дель, использующая-¦ ¦ ¦ ¦ ¦ ¦ся для автономных¦ ¦ ¦ ¦ ¦ ¦программ на Ассемб-¦ ¦ ¦ ¦ ¦ ¦лере. ¦ ¦ ¦ ¦ ¦ ¦ ¦ +---------+---------+--------+--------------+-------------------+ ¦MEDIUM ¦ дальний ¦ближний ¦cs= ¦Для кода использу-¦ ¦ ¦ ¦ ¦<модуль>_text ¦ется несколько сег-¦ ¦ ¦ ¦ ¦ds=ss=dgroup ¦ментов, по одному¦ ¦ ¦ ¦ ¦ ¦на модуль. Данные¦ ¦ ¦ ¦ ¦ ¦находится в группе¦ ¦ ¦ ¦ ¦ ¦с именем DGROUP. ¦ ¦ ¦ ¦ ¦ ¦ ¦ +---------+---------+--------+--------------+-------------------+ ¦COMPACT ¦ ближний ¦дальний ¦cs=_text ¦Код находится в од-¦ ¦ ¦ ¦ ¦ds=ss=dgroup ¦ном сегменте. Все¦ ¦ ¦ ¦ ¦ ¦ближние данные на-¦ ¦ ¦ ¦ ¦ ¦ходятся в группе с¦ ¦ ¦ ¦ ¦ ¦именем DGROUP. Для¦ ¦ ¦ ¦ ¦ ¦ссылки на данные¦ ¦ ¦ ¦ ¦ ¦используются даль-¦ ¦ ¦ ¦ ¦ ¦ние указатели. ¦ ¦ ¦ ¦ ¦ ¦ ¦ +---------+---------+--------+--------------+-------------------+ ¦LARGE ¦ дальний ¦дальний ¦cs= ¦Для кода использу-¦ ¦ ¦ ¦ ¦<модуль>_text ¦ется несколько сег-¦ ¦ ¦ ¦ ¦ds=ss=dgroup ¦ментов, по одному¦ ¦ ¦ ¦ ¦ ¦на модуль. Все¦ ¦ ¦ ¦ ¦ ¦ближние данные на-¦ ¦ ¦ ¦ ¦ ¦ходятся в группе с¦ ¦ ¦ ¦ ¦ ¦именем DGROUP. Для¦ ¦ ¦ ¦ ¦ ¦ссылки на данные¦ ¦ ¦ ¦ ¦ ¦используются даль-¦ ¦ ¦ ¦ ¦ ¦ние указатели. ¦ ¦ ¦ ¦ ¦ ¦ ¦ +---------+---------+--------+--------------+-------------------+ ¦HUGE ¦ дальний ¦дальний ¦cs= ¦То же, что модель¦ ¦ ¦ ¦ ¦<модуль>_text ¦LARGE (что касается¦ ¦ ¦ ¦ ¦ds=ss=dgroup ¦Турбо Ассемблера). ¦ ¦ ¦ ¦ ¦ ¦ ¦ +---------+---------+--------+--------------+-------------------+ ¦TCHUGE ¦ дальний ¦дальний ¦cs= ¦Это эквивалентно¦ ¦ ¦ ¦ ¦<модуль>_text ¦модели LARGE, но с¦ ¦ ¦ ¦ ¦ds=nothing ¦другими предположе-¦ ¦ ¦ ¦ ¦ss=nothing ¦ниями о сегментных¦ ¦ ¦ ¦ ¦ ¦регистрах. ¦ ¦ ¦ ¦ ¦ ¦ ¦ +---------+---------+--------+--------------+-------------------+ ¦TPASCAL ¦ ближний ¦дальний ¦cs=code, ds ¦Эта модель поддер- ¦ ¦ ¦ ¦ ¦=data, ss= ¦живается ранними¦ ¦ ¦ ¦ ¦nothing ¦версиями Турбо Пас-¦ ¦ ¦ ¦ ¦ ¦каля. В более позд-¦ ¦ ¦ ¦ ¦ ¦них версиях не тре-¦ ¦ ¦ ¦ ¦ ¦буется. ¦ ¦ ¦ ¦ ¦ ¦ ¦ +---------+---------+--------+--------------+-------------------+ ¦FLAT ¦ ближний ¦ближний ¦cs=_text ¦То же, что и модель¦ ¦ ¦ ¦ ¦ds=ss=flat ¦SMALL, но подходит¦ ¦ ¦ ¦ ¦ ¦для использования в¦ ¦ ¦ ¦ ¦ ¦OS/2. ¦ L---------+---------+--------+--------------+--------------------
Таблица 3. Упрощенные директивы определения сегмента
Формат директивы (режим MASM)
| Формат директивы (режим IDEAL)
| Назначение
|
.CODE [имя]
| CODESEG[имя]
| Начало или продолжение сегмента кода
|
.DATA
| DATASEG
| Начало или продолжение сегмента инициализированных данных. Также используется для определения данных типа near
|
.CONST
| CONST
| Начало или продолжение сегмента постоянных данных (констант) модуля
|
.DATA?
| UDATASEG
| Начало или продолжение сегмента неинициализированных данных. Также используется для определения данных типа near
|
.STACK [размер]
| STACK [размер]
| Начало или продолжение сегмента стека модуля. Параметр [размер] задает размер стека
|
.FARDATA [имя]
| FARDATA [имя]
| Начало или продолжение сегмента инициализированных данных типа far
|
.FARDATA? [имя]
| UFARDATA [имя]
| Начало или продолжение сегмента неинициализированных данных типа far
|
Наличие в некоторых директивах параметра [имя] говорит о том, что возможно определение нескольких сегментов этого типа.
Процедура – группа команд для решения конкретной подзадачи.
Синтаксис процедуры:
имя_процедуры PROC [[модификатор_языка ] язык] [расстояние ]
команды
[имя_процедуры ] ENDP
Пример
model small
.stack 100h
.data
.code
my_proc procnear
ret
my_proc endp
start:
end start
процедуру можно распологать в конце программы либо вкладывать в другую. Во втором случае неоходимо предусмотреть обход тела процедуры, ограниченного директивами PROC и ENDP, с помощью JMP/
Команда CALL осуществляет вызов процедуры (подпрограммы). Синтаксис команды:
call [модификатор] имя_процедуры
Подобно команде JMP команда CALL передает управление по адресу с символическим именем имя_процедуры, но при этом в стеке сохраняется адрес возврата (то есть адрес команды, следующей после команды CALL).
Команда RET считывает адрес возврата из стека и загружает его в регистры CS и EIP/IP, тем самым возвращая управление на команду, следующую в программе за командой CALL Синтаксис команды:
ret [число]
Необязательный параметр [число] обозначает количество элементов, удаляемых из стека при возврате из процедуры.
Как и в случае команды JMP, вызов процедуры командой CALL может быть внутрисегментным и межсегментным.