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

Листинг 2.3. Модифицированная версия Add_Int.

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


Читайте также:
  1. Версия v 12.6
  2. Версия вторая. Корыстно-финансовая
  3. Версия первая. Официальная
  4. Версия третья. Тамплиеры против Церкви
  5. Запоздалая конверсия
  6. Инверсия
  7. Инверсия реальности

.MODEL MEDIUM,С; использовать модель MEDIUM; и соглашения по вызову Си

.CODE; начало кода

 

PUBLIC _Add_Int; объявляем функцию как общедоступную

_Add_lnt PROC USES integer_1:WORD, integer_2:WORD

mov AX,integer_l; загрузить первый операнд в AХ

add AX,integer_2; сложить второй операнд с AХ

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

END; конец кода

Как видно из Листинга 2.3, тяжкое бремя сохранения регистра ВР, создания и уничтожения стекового фрейма теперь отдано на откуп ассемблеру. Более того мы получили прямой доступ к параметрам integer 1 и integer 2.

Передача указателей

Мы знаем, как передать значения таких параметров как BYTE или WORD, но как передать указатель? Указатели передаются как двойные слова, или DWORD. Для доступа к указателям в стеке нам придется воспользоваться старым приемом: разобьем двойное слово указателя на две переменные segment и offset, которые будут иметь тип WORD, и уже к ним будем обращаться в. нашей ассемблерной программе. К примеру, если мы вызываем ассемблерную функцию в модели MEDIUM, (скажем, это будет вызов типа FAR) в следующей строке:

pfoo(&x)

то получить адрес переменной Х можно будет с помощью следующих подстановок:

offset EQU [ВР+6] segment EQU [BP+8]

Если мы захотим изменить значение X, то нам придется сделать следующее:

mov DI,offset

mov AX,segment

mov ES,AX

mov ES:[DI],CX

Эта программа состоит из двух основных частей:

§ Во-первых, создается указатель на Х через регистры ES и DI;

§ Во-вторых, изменяется значение переменной X.

Ну вот и все о том, что связано с передачей параметров. Новые расширения директив PROC и USES просто великолепны, и вы можете всегда ими пользоваться, если чувствуете от их применения комфорт. Если вы предпочитаете все делать в стиле MASM 5.0, то это ваше право. С точки зрения быстродействия программы здесь нет никакой разницы.

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

Теперь вы знаете, как передавать переменные в процедуры, а вот как насчет временных и локальных переменных, которые действуют только внутри процедуры?

Когда мы пишем программы на Си, то применяем локальные переменные для вычислений, сохранения результатов и т. д. Так же, как и в Си, мы можем создать локальные переменные в наших ассемблерных функциях, используя стек. Конечно, можно создать локальные переменные в области данных (например, в сегменте данных), но этого не стоит делать. Почему? Дело в том, что стек как раз и создавался для временного хранения данных и локальных переменных, так что именно им и стоит пользоваться.

Давайте посмотрим, как это делается. Когда мы определяем стек, сохраняя регистр ВР, то можем извлекать параметры путем прибавления положительного смещения к регистру ВР, например, [ВР+6] и т. д. Таким образом, получается, что в действительности стек — это область непрерывной памяти, которую мы можем использовать также и для хранения локальных переменных. Для этого нам надо только использовать отрицательное смещение относительно регистра ВР.

В случае, если мы хотим иметь две локальные переменные 1осаl_1 и 1оса1_2, можно использовать следующую подстановку:

local_1 EQU [ВР-2]

local_2 EQU [BP-4]

Это дает нам два целых числа. Пока нам не известно, что записано по этим адресам и мы можем только предполагать, что данный участок памяти можно использовать безболезненно. Однако нужно помнить, что мы только что использовали стек для хранения данных и теперь нам необходимо самим изменить регистр SP для отражения этого. Если этого не сделать, то первая встретившаяся инструкция PUSH обязательно что-нибудь запишет в нашу переменную и непременно «испортит» ее.

Для исключения этой ситуации можно предложить уменьшить значение регистра SP на длину переменных, которые мы хотим сохранить. В нашем случае это составит четыре байта. В Листинге 2.4 показано, как это сделать.

 


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


<== предыдущая страница | следующая страница ==>
Листинг 2.2. Простая процедура сложения.| Листинг 2.4. Корректировка регистра SP.

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