Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по МО.doc
Скачиваний:
47
Добавлен:
01.06.2015
Размер:
353.79 Кб
Скачать

2.4. Сохранение регистров

Каждая подпрограмма должна либо сохранять значения всех регистров процессора (кроме тех, которые используются для воз­врата результатов), либо, в крайнем случае, в описании подпро­граммы должно быть четко указано, какие регистры она портит. Для сохранения регистров используется стек. Команды push слу­жат для помещения регистров в стек, а pop – для их восстановле­ния перед возвратом из подпрограммы. Сохранение регистров должно выполняться после загрузки BP (см. предыдущий параграф).

2.5. Локальные переменные

Переменные, размещенные в сегменте данных, являются ста­тическими (аналогично переменным с классом static в Си). Конечно, их можно рассматривать как локальные переменные подпрограмм, обеспечив локализацию области действия с помо­щью директивы locals (см. ниже). Однако такое статическое рас­пределение памяти под локальные переменные не соответствует понятию локальных переменных в блочных языках типа Pascal или C, поскольку время существования таких переменных – время существования программы. Для того чтобы решить данную проблему, т.е. обеспечить динамическое распределение памяти под локальные переменные, следует выделять для них память в стеке (как это делается в Pascal или C).

Предположим, что в подпрограмме должно быть две локальные переменные длиной в слово. Чтобы обеспечить выделение памяти, для них перед командами сохранения регистров следует добавить команду:

sub SP, 4

которая резервирует в стеке два слова.

После выполнения этой команды стек будет выглядеть сле­дующим образом:

1-я лок.пер.

SP

2-я лок.пер.

BP

сохраненное значение BP

IP

адрес возврата

2-й параметр

параметр, занесенный в стек вторым

1-й параметр

параметр, занесенный в стек первым

. . .

И, если определить структуру:

__locvars struc

__var1 dw ?

__var2 dw ?

__locvars ends,

то доступ к локальным переменным можно осуществить с помо­щью команд:

mov AX, __var1[BP-4];загрузить в AX значение 1-й локальной переменной mov BX, __var2[BP-4];загрузить в BX значение 2-й локальной переменной

Чистка стека от локальных переменных должна выполняться после восстановления сохраненных регистров, это можно сделать с помощью команды:

add SP, 4

или

mov SP, BP

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

Директива model позволяет вам задать для программы не­сколько стандартных моделей сегментации. Вы можете также ис­пользовать ее для задания языка для процедур программы. Она имеет следующий синтаксис:

model [модификатор_модели] модель_памяти[имя_сегмента_кода] [,[модификатор_языка] язык] [, модификатор_модели]

модель_памяти и модификатор_модели определяют модель сег­ментации памяти, используемую в программе.

В применяемых в Турбоассемблере стандартных моделях можно использовать специальные сегменты для: кода; инициали­зированных данных; неинициализированных данных; инициали­зированных данных дальнего типа; неинициализированных дан­ных дальнего типа; констант; стека.

Сегмент кода содержит обычно код модуля (но при необходи­мости может также содержать данные). В целях совместимости с языками высокого уровня инициализированные данные и кон­станты интерпретируются по-разному. Они содержат такие дан­ные, как сообщения, когда важно начальное значение. Неинициа­лизированные данные и стек содержат данные, начальные значе­ния которых не существенны. Инициализированные данные даль­него типа (far) – это неинициализированные данные, которые не являются частью стандартного сегмента данных и которые дос­тупны только при изменении значения сегментного регистра. Это же относится к неинициализированным данным дальнего типа.

Единственным обязательным параметром директивы model яв­ляется модель памяти. Каждая стандартная модель памяти опи­сывается в табл. 1.

Таблица 1

Модель

Код

Данные

Предполагаемые регистры

Описание

TINY

near

near

cs=dgroup ds=ss=dgroup

Весь код и все данные комбиниру­ются¦ в одну группу с¦ именем DGROUP. Эта¦ модель использу­ется¦ для про­грамм, ассемблируе­мых в формат .COM. Некоторые¦ языки эту модель не¦ поддержи­вают.

SMALL

near

near

cs=_text ds=ss=dgroup

Код представляет собой один сег­мент. Все данные комбинируются в группу с именем DGROUP. Это наиболее общая модель, исполь­зующаяся для авто­номных про­грамм на ассемблере.

MEDIUM

far

near

cs=<модуль>_text ds=ss=dgroup

Для кода используется несколько сегментов, по одному на модуль. Дан­ные находятся в группе с име­нем DGROUP.

COMPACT

near

far

cs=_text ds=ss=dgroup

Код находится в одном сегменте. Все ближние данные находятся в группе с именем DGROUP. Для ссылки на данные используются дальние указатели.

Окончание табл. 1

Модель

Код

Данные

Предполагаемые регистры

Описание

LARGE

far

far

cs=<модуль>_text ds=ss=dgroup

Для кода используется несколько сегментов, по одному на модуль. Все ближние данные нахо­дятся в группе с именем DGROUP. Для ссылки на данные используются дальние указатели.

HUGE

far

far

cs=<модуль>_text ds=ss=dgroup

То же, что модель LARGE (что ка­сается Турбоассемб­лера).

FLAT

near

near

cs=_text ds=ss=flat

То же, что и модель SMALL, но подходит для использования в OS/2 и Win32.

Поле модификатор_модели позволяет вам изменить отдельные аспекты модели. Вы можете задавать при необходимости не­сколько модификаторов модели. Доступные модификаторы модели приведены в табл. 2.

Таблица 2

Модификатор модели

Функция

NEARSTACK

Указывает, что сегмент стека должен включаться в DGROUP (если группа DGROUP присутствует), а SS должен указывать на DGROUP.

FARSTACK

Указывает, что сегмент стека не должен включаться в DGROUP, а SS должен указывать не nothing (не определен).

USE16

Задает, что все сегменты в выбранной модели должны быть 16-разрядными (при выборе процессора 80386 или старше).

USE32

Задает, что все сегменты в выбранной модели должны быть 32- разрядными (при выборе процессора 80386 или старше).

DOS, OS_DOS

Задает, что прикладная программа ориентируется на DOS.

OS2, OS_OS2

Задает, что прикладная программа ориентируется на OS2, Win32.

Язык и модификатор_языка вместе определяют соглашения, ис­поль­зуемые при вызове процедуры, а также используемый по умолча­нию характер начала и завершения кода каждой проце­дуры. Они определяют так же, как будут объявляться общедоступ­ные иден­тификаторы (которые использует компоновщик).