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

Директива USES


Надо сказать, что ассемблер MASM, начиная с версии 5.1, имеет некоторые новые директивы, упрощающие порядок передачи параметров и создания фрейма стека. Для этого вы можете использовать директиву USES вместе с директивой PROC. Они сообщат ассемблеру, какие именно регистры будут использоваться в функции. Директива USES оберегает вас от всей рутины, связанной с определением стекового фрейма и подстановками переменных. Более того, она генерирует код пролога и эпилога для сохранения регистров, которые вы указали для использования в функциях. Таким образом, содержимое этих регистров не будет изменено, когда процедура вернет управление вызвавшей ее Си-функции.

Внимание!

Помните, что Си и ассемблер используют одни и те же регистры процессора. Если вы пользуетесь регистром в ассемблерной программе, то должны его сохранить в стеке и восстановить перед завершением функции. Иначе, ваша Си-программа может просто "сломаться" в момент выхода из вызова ассемблерной вставки.

Директива PROC и относящийся к ней уточнитель USES имеет следующий синтаксис.

label PROC [[attributes]] [[USES register_list]] [[,]]

[[parameter list][:type]]...]]

§

Поле label — это имя процедуры;

§          Поле attributes сообщает ассемблеру свойства вашей процедуры. Она может содержать множество параметров, таких как тип процедуры (NEAR или FAR), «видимость» процедуры (PUBLIC или PRIVATE) и, наконец, тип языка (С, PASCAL и т. д.). Эта возможность делает наши программы на ассемблере более читаемыми. Правда, это связывает руки, но зато программы обретают определенную элегантность;

§          Поле register_list показывает, какие регистры будет использовать функция. При этом ассемблер генерирует код, который может сохранить их на время работы процедуры и восстановить при выходе;

§          Поле parameter_list очень похоже на список параметров в Си;

Для каждой передаваемой процедуре переменной должен быть указан тип, определяющий их размер (например, BYTE или WORD).




Тип задается в поле type.

Если вы пишите процедуру, в которую передаете три целых величины, и будете использовать регистры SI, DI и СХ, то должны включить следующий оператор:

far proc USES SI DI СХ, integer_1:WORD, integer_2:WORD,

                             integer_3:WORD

Используя директивы PROC и USES, давайте перепишем процедуру из Листинга 2.2.                                 

Листинг 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.


Содержание раздела