Пример 2. Динамическая библиотека

Написание динамических библиотек под Win32 также значительно упростилось, по сравнению с тем, как это делалось под Windows 3.x. Исчезла необходимость вставлять startup код, а использование четырёх событий инициализации/деинициализации на уровне процессов и потоков, кажется логичным.

Рассмотрим простой пример динамической библиотеки, в которой всего одна функция, преобразования целого числа в строку в шестнадцатеричной системе счисления.

Файл mylib.asm

Ideal

P586

Radix  16

Model  flat

DLL_PROCESS_ATTACH  = 1


extrn  GetVersion:  proc


DataSeg

hInst     dd   0

OSVer     dw   0


CodeSeg

proc  libEntry   stdcall

arg   @@hInst    :dword,    @@rsn  :dword,    @@rsrv :dword

       cmp   [@@rsn],DLL_PROCESS_ATTACH

       jne   @@1

       call  GetVersion

       mov   [OSVer],ax

       mov   eax,[@@hInst]

       mov   [hInst],eax

@@1:     mov   eax,1

       ret

endP  libEntry


public stdcall    Hex2Str

proc  Hex2Str    stdcall

arg   @@num  :dword,    @@str  :dword

uses  ebx

       mov   eax,[@@num]

       mov   ebx,[@@str]

       mov   ecx,7

@@1:     mov   edx,eax

       shr   eax,4

       and   edx,0F

       cmp   edx,0A

       jae   @@2

       add   edx,'0'

       jmp   @@3

@@2:     add   edx,'A' - 0A

@@3:     mov   [byte ebx + ecx],dl

       dec   ecx

       jns   @@1

       mov   [byte ebx + 8],0

       ret

endp  Hex2Str


end   libEntry


Остальные файлы, которые необходимы для данного примера, можно найти в приложении 2.

Краткие комментарии к динамической библиотеке

Процедура libEntry является точкой входа в динамическую библиотеку, её не надо объявлять как экспортируемую, загрузчик сам определяет её местонахождение. LibEntry может вызываться в четырёх случаях:

— при проецировании библиотеки в адресное пространство процесса (DLL_PROCESS_ATTACH);

— при первом вызове библиотеки из потока (DLL_THREAD_ATTACH), например, с помощью функции LoadLibrary;

— при выгрузке библиотеки потоком (DLL_THREAD_DETACH);

— при выгрузке библиотеки из адресного пространства процесса (DLL_PROCESS_DETACH).

В нашем примере обрабатывается только первое из событий DLL_PROCESS_ATTACH. При обработке данного события библиотека запрашивает версию OS сохраняет её, а также свой handle of instance.

Библиотека содержит только одну экспортируемую функцию, которая собственно не требует пояснений. Вы, пожалуй, можете обратить внимание на то, как производится запись преобразованных значений. Интересна система адресации посредством двух регистров общего назначения: ebx + ecx, она позволяет нам использовать регистр ecx одновременно и как счётчик и как составную часть адреса.

Загрузка...