Пример использования оператора INVOKE
Рисунок 1.1.6. Пример использования оператора INVOKE.
Как видите, внешняя процедура объявляется теперь при помощи директивы PROTO. Данная директива позволяет при необходимости указывать и наличие параметров. Например, строка
PROC1 PROTO :DWORD, :WORD
будет означать, что процедура требует два параметра длиной в четыре и два байта (всего 6, т.е. @6).
Как уже говорилось, я буду редко использовать оператор INVOKE. Теперь я назову первую причину такого пренебрежения к данной возможности. Дело в том, что я сторонник чистоты языка ассемблера и любое использование макросредств вызывает у меня чувство несовершенства. На мой взгляд, и начинающим программистам не стоит увлекаться макросредствами, иначе не чувствуется вся красота этого языка. О второй причине Вы узнаете ниже.
На нашей схеме, на Рисунок 1.1, говорится не только о возможности подсоединения объектных модулей, но и библиотек. Собственно, если объектных модулей несколько, то это по понятным причинам вызовет неудобства. Поэтому объектные модули объединяются в библиотеки. Для подсоединения библиотеки в MASM удобнее всего использовать директиву INCLUDELIB, которая сохраняется в объектном коде и используется программой LINK.EXE.
Но как создать библиотеку из объектных модулей? Для этого имеется специальная программа, называемая библиотекарем. Предположим, мы хотим создать библиотеку LIB1.LIB, состоящую из одного модуля - PROG2.OBJ. Выполним для этого следующую команду: LIB /OUT:LIB1.LIB PROG2.OBJ.
Если необходимо добавить в библиотеку еще один модуль (MODUL.OBJ), то достаточно выполнить команду: LIB LIB1.LIB MODUL.OBJ.
Вот еще два полезных примера использования библиотекаря:
LIB /LIST LIB1.LIB - выдает список модулей библиотеки.
LIB /REMOVE:MODUL.OBJ LIB1.LIB - удаляет из библиотеки модуль MODUL.OBJ.
Вернемся теперь к нашему примеру. Вместо объектного модуля мы используем теперь библиотеку LIB1.LIB. Видоизмененный текст программы PROG1.ASM представлен на Рисунок 1.7.
.386P ; плоская модель .MODEL FLAT, STDCALL ;-------------------------------------------------- ; прототип внешней процедуры EXTERN PROC1@0:NEAR ;-------------------------------------------------- INCLUDELIB LIB1.LIB ;-------------------------------------------------- ; сегмент данных _DATA SEGMENT DWORD PUBLIC USE32 'DATA' _DATA ENDS ; сегмент кода _TEXT SEGMENT DWORD PUBLIC USE32 'CODE' START: CALL PROC1@0 RET ; выход _TEXT ENDS END START