Текст динамической библиотеки и программы
IV
На Рисунок 3.3.5 представлен текст динамической библиотеки и программы, вызывающей процедуру из этой библиотеки. Здесь ничего сложного, просто я хотел продемонстрировать, что основной процесс и динамическая библиотека используют одно и тоже адресное пространство. Процесс передает адреса строк, которые находятся в блоке данных основного процесса. В свою очередь, процедура возвращает в основной процесс адрес строки, находящейся в блоке данных динамической библиотеки.
; динамическая библиотека DLL2.ASM .386P ; плоская модель IFDEF MASM .MODEL FLAT, stdcall ELSE .MODEL FLAT ENDIF
PUBLIC DLLP1
; константы ; сообщения, приходящие при открытии ; динамической библиотеки DLL_PROCESS_DETACH equ 0 DLL_PROCESS_ATTACH equ 1 DLL_THREAD_ATTACH equ 2 DLL_THREAD_DETACH equ 3
IFDEF MASM ; MASM ; прототипы внешних процедур EXTERN MessageBoxA@16:NEAR ; директивы компоновщику для подключения библиотек includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ELSE ; TASM EXTERN MessageBoxA:NEAR MessageBoxA@16 = MessageBoxA includelib c:\tasm32\lib\import32.lib ENDIF ;--------------------------------------------------
; сегмент данных _DATA SEGMENT DWORD PUBLIC USE32 'DATA' TEXT DB "Строка в динамической библиотеке",0 _DATA ENDS
; сегмент кода _TEXT SEGMENT DWORD PUBLIC USE32 'CODE' ; [EBP+10H] ; резервный параметр ; [EBP+0CH] ; причина вызова ; [EBP+8] ; идентификатор DLL-модуля DLLENTRY: MOV EAX,DWORD PTR [EBP+0CH] CMP EAX,0 JNE D1 ; закрытие библиотеки JMP _EXIT D1: CMP EAX,1 JNE _EXIT ; открытие библиотеки _EXIT: MOV EAX,1 RET 12 ;--------------------- ; адреса параметров ; [EBP+8] ; [EBP+0CH] DLLP1 PROC EXPORT PUSH EBP MOV EBP,ESP PUSH 0 PUSH DWORD PTR [EBP+0CH] PUSH DWORD PTR [EBP+8] PUSH 0 CALL MessageBoxA@16 POP EBP LEA EAX,TEXT RET 8 DLLP1 ENDP _TEXT ENDS END DLLENTRY
; основной модуль DLLEX2.ASM, вызывающий ; процедуру из динамической библиотеки .386P ; плоская модель .MODEL FLAT, stdcall ; константы ; прототипы внешних процедур IFDEF MASM ; MASM EXTERN GetProcAddress@8:NEAR EXTERN LoadLibraryA@4:NEAR EXTERN FreeLibrary@4:NEAR EXTERN ExitProcess@4:NEAR EXTERN MessageBoxA@16:NEAR includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ELSE ; TASM includelib c:\tasm32\lib\import32.lib EXTERN GetProcAddress:NEAR EXTERN LoadLibraryA:NEAR EXTERN FreeLibrary:NEAR EXTERN ExitProcess:NEAR EXTERN MessageBoxA:NEAR GetProcAddress@8 = GetProcAddress LoadLibraryA@4 = LoadLibraryA FreeLibrary@4 = FreeLibrary ExitProcess@4 = ExitProcess MessageBoxA@16 = MessageBoxA ENDIF ;---------------------------------------------- ; сегмент данных _DATA SEGMENT DWORD PUBLIC USE32 'DATA' TXT DB 'Ошибка динамической библиотеки',0 MS DB 'Сообщение',0 LIBR DB 'DLL2.DLL',0 HLIB DD ? MS1 DB 'Сообщение из библиотеки',0 TEXT DB 'Строка содержится в основном модуле',0 IFDEF MASM NAMEPROC DB '_DLLP1@0',0 ELSE NAMEPROC DB 'DLLP1',0 ENDIF _DATA ENDS
; сегмент кода
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE' ; [EBP+10H] ; резервный параметр ; [EBP+0CH] ; причина вызова ; [EBP+8] ; идентификатор DLL-модуля START: ; загрузить библиотеку PUSH OFFSET LIBR CALL LoadLibraryA@4 CMP EAX,0 JE _ERR MOV HLIB,EAX ; получить адрес PUSH OFFSET NAMEPROC PUSH HLIB CALL GetProcAddress@8 CMP EAX,0 JNE YES_NAME ; сообщение об ошибке _ERR: PUSH 0 PUSH OFFSET MS PUSH OFFSET TXT PUSH 0 CALL MessageBoxA@16 JMP _EXIT YES_NAME: PUSH OFFSET MS1 PUSH OFFSET TEXT CALL EAX PUSH 0 PUSH OFFSET MS PUSH EAX PUSH 0 CALL MessageBoxA@16 ; закрыть библиотеку PUSH HLIB CALL FreeLibrary@4 ; библиотека автоматически закрывается также ; при выходе из программы ; выход _EXIT: PUSH 0 CALL ExitProcess@4 _TEXT ENDS END START