Студопедия

Главная страница Случайная страница

Разделы сайта

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






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






.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 показано, как это сделать.

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.