Программирование игр для Windows. Советы профессионала


Передача параметров - часть 2


Как известно, значение смещения занимает два байта. Если же мы применяем модель памяти MEDIUM или LARGE, то должны сохранить как смещение, так и сегментную часть адреса. Вместе сегмент и смещение занимают уже целых четыре байта.                         

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

Листинг 2.2. Простая процедура сложения.

; Секция констант

integer_1 EQU [ВР+6]        ; задает адрес первого аргумента

integer_2 EQU [BP+8]        ; задает адрес второго аргумента

.MODEL medium                ; указываем компилятору, что он должен

; использовать модель памяти MEDIUM

.CODE                        ; начало кодового сегмента

PUBLIC _Add_Int              ; эта функция - общедоступна

_Add_Int PROC FAR            ; имя функции и ее тип (дальняя)

push BP                      ; эти две инструкции инициализируют

; фрейм стека

mov ВР, SP

mov AX,integer_1             ; помещаем первое слагаемое

; в аккумулятор (регистр АХ)

add AX,integer_2             ; добавляем второе, слагаемое

; к содержимому АХ

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

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

END                          ; конец кодового сегмента

Единственное, что мы изменили по сравнению с Листингом 2.1, это добавили несколько строк кода и ввели определения для адресов параметров. Теперь давайте проанализируем то, что у нас получилось.

§          Как и в предыдущем листинге, здесь были использованы директивы ассемблера для указания модели памяти, способа вызова, начала и конца функции;

§          EQU — это простая директива, заменяющая одну строку на другую. Я прибег к ней потому, что мне не хотелось в тексте самой функций использовать синтаксические конструкции [ВР+6] и [BP+8]. Строки, задающие выражения, которые будут подставлены при компиляции, это:

integer_l EQU [ВР+6]

integer_2 EQU [BP+8]

В общем, использование таких подстановок позволяет сделать ассемблерную программу более читабельной. Единственной альтернативой такому подходу является написание команды индексирования относительно содержимого одного из регистров (типа [ВР+6]).




Начало  Назад  Вперед