Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

Листинг 2.1. Прототип процедуры для MASM 5.0 и более старших версий.

ВВЕДЕНИЕ | ВИДЕОИГРЫ. ПЕРВЫЕ ШАГИ... | Листинг 2.3. Модифицированная версия Add_Int. | Листинг 2.4. Корректировка регистра SP. | Листинг 2.5. Программа Timer. | Листинг 2.7. Ассемблерная часть примера. | Листинг 2.9. Си-функция, тестирующая видеорежим (SETMOPEC.C). | Листинг 2.11, Программа на Си для тестирования программы 2.10 (FILLC.C). | ОСНОВЫ РАБОТЫ С УСТРОЙСТВАМИ ВВОДА | Листинг 3.1. Чтение кнопок джойстика. |


Читайте также:
  1. I I . Выполнение процедуры
  2. Quot;Зависть есть Беспокойство души, вызван­ное сознанием того. что желанным нам бла­гом обладает другой человек, которого мы не считаем более нас достойным владеть им".
  3. Аксиома позиций 4 Если мы решаем проблемы, то позиция, или установка, играет более важную роль, чем что-либо другое
  4. А]. [Стих 20]. "И всякий остров убежал, и гор не стало" означает, что не было более никакой истины веры и никакого добра любви.
  5. Более 40 видов мобильных телефонов.
  6. Более 45 видов наушников.
  7. Более 70% каменного угля сосредоточено в__________ странах

.MODEL MEDIUM;тип модели памяти

.CODE

; начало кода

PUBLIC _function_name;информация для компоновщика. Функция

;может экспортироваться

_function_name PROC FAR;название и тип функции(ближняя

;или дальняя). Ближние функции можно использовать для моделей

;памяти SMALL и COMPACT, а дальние применяются для моделей

;памяти MEDIUM, LARGE и HUGE.

push ВР;готовим фрейм стека–пролог

;функции

mov BP,SP;сохраним стек

;Работа функции

pop ВР;восстанавливаем фрейм стека

;эпилог функции

_function_name ENDP; конец процедуры

END

;конец кода

Давайте проанализируем программу, приведенную в Листинге 2.1.

§ Первая директива, которую мы встречаем — это.MODEL. Как и компилятор Си, MASM должен знать, какая из моделей памяти используется. Ключевое слово MEDIUM означает, что мы собираемся использовать модель памяти именно типа MEDIUM. Теперь я хочу напомнить вам свойства основных моделей памяти:

· Модель SMALL имеет один 64-килобайтный сегмент для кода и один сегмент для данных;

· Модель COMPACT имеет один 64-килобайтный сегмент для кода и несколько сегментов данных;

· Модель MEDIUM имеет один 64-килобайтный сегмент для данных и несколько сегментов для кода;

· Модель LARGE имеет несколько сегментов как для кода, так и для данных;

· Модель HUGE разрешает данным быть больше, чем 64К,но в остальном полностью похожа на модель LARGE.

Чаще всего мы будем использовать модели памяти MEDIUM и LARGE.

§ Следующая директива — PUBLIC. Она говорит MASM, что следующее имя будет экспортировано, то есть станет «видимо» из других модулей;

§ Теперь мы переходим к началу самой функции. В ассемблере функция начинается с директивы PROC, которая следует сразу за именем функции;

§ В этом месте мы находимся внутри исполняемой части кода. Первые две инструкции устанавливают стек таким образом, что процедура получает доступ к параметрам, передаваемым через стек. К этому мы еще не раз вернемся;

§ В конце процедуры мы очищаем стек;

§ В конце каждой процедуры ставится ключевое слово ENDP;

§ В одном блоке мы можем иметь сколько угодно процедур, но надо помнить, что самой последней должна быть директива END. Она сообщает ассемблеру об окончании программы.

Тема следующего разговора - это передача параметров. Наши ассемблерные функции не были бы так полезны, если б мы не имели возможности обмениваться с ними информацией,

Передача параметров

Языки Си и ассемблер похожи на дальних родственников, живущих в одном доме - они вынуждены придерживаться сложных взаимных условностей. Однако ассемблер значительно более примитивен. Поэтому при передаче параметров ассемблерной процедуре нам приходится сочинять множество дополнительных строк кода, обеспечивающих доступ к ним. Вначале необходимо оформить фрейм стека, как показано в Листинге 2.1. Далее необходимо получить доступ к переданным параметрам, основываясь на новом значении регистра базы (ВР). Для обеспечения доступа к параметрам вы должны четко представлять себе, как именно передаваемые параметры размещаются в стеке. К примеру, вы хотите написать процедуру, вычисляющую сумму двух чисел и возвращающую результат в регистре АХ. На языке Си, описание этой функции выглядит так:

int Add_Int(int number_1, int number_2);

При выполнении этой процедуры компилятор языка Си создаст фрейм стека и поместит туда параметры. Иными словами, значения number_1 и number_2 будут расположены в стеке. Вы можете подумать, что сначала в стек будет помещено значение number 1, а затем - number_2. Однако компилятор Си думает несколько иначе. Он помещает параметры в стек в обратном порядке, что облегчает доступ к ним. За счет применения обратного порядка размещения параметров, адрес каждого из них будет задаваться некоторым положительным смещением относительно регистра ВР, что делает жизнь намного легче. В частности, именно благодаря такому механизму, некоторые функции (например, printf) могут получать переменное число параметров. Таким образом, при вызове функции Add_Int фрейм стека будет выглядеть, как показано па рисунке 2.1 или 2.2, в зависимости от используемой модели памяти. Причина, по которой вид фрейма стека зависит от модели памяти, состоит в следующем: при вызове процедуры в стек помещается адрес команды, следующей непосредственно за командой вызова. Если мы применили модель памяти SMALL, все процедуры по определению находятся внутри одного кодового сегмента. Следовательно, для доступа из программы к любой из них нам необходимо знать только смещение. Как известно, значение смещения занимает два байта. Если же мы применяем модель памяти MEDIUM или LARGE, то должны сохранить как смещение, так и сегментную часть адреса. Вместе сегмент и смещение занимают уже целых четыре байта.

Как видно из рисунков 2.1 и 2.2, параметры помещаются в стек в том порядке, который обеспечивает их адресацию положительными смещениями относительно значения регистра базы (ВР). Следовательно, для доступа к параметру number 1 вы должны использовать [ВР+4] или [ВР+6], в зависимости от установленной модели памяти. В качестве примера рассмотрим полный текст функции Add_Int. Она вычисляет сумму двух передаваемых в качестве аргументов чисел. Результат возвращается в регистре АХ, который, в соответствии с соглашениями языка Си, используется для возврата 16-битных значений.


Дата добавления: 2015-07-12; просмотров: 84 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
ОСНОВЫ ЯЗЫКА АССЕМБЛЕРА| Листинг 2.2. Простая процедура сложения.

mybiblioteka.su - 2015-2024 год. (0.007 сек.)