На этом шаге мы рассмотрим использование общего адресного пространства.
В следующей программе представлен текст динамической библиотеки и программы, вызывающей процедуру из этой библиотеки. Здесь ничего сложного, просто мы хотели продемонстрировать, что основной процесс и динамическая библиотека используют одно и то же адресное пространство. Процесс передает адреса строк, которые находятся в блоке данных основного процесса. В свою очередь, процедура возвращает в основной процесс адрес строки, находящейся в блоке данных динамической библиотеки.
Файл pr73_1.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 ;Директивы компоновщику для подключения библиотек. ;Для компоновщика LINK.EXE. includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib ELSE ;TASM EXTERN MessageBoxA@: NEAR MessageBoxA@16 = MessageBoxA ;Для компоновщика TLINK32.EXE. 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] - Резервный параметр. ; [ЕВР+0СН] - Причина вызова. ; [ЕВР+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] ; [ЕВР+0СН] 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
Файл pr73_2.asm - основной модуль, вызывающий процедуру из DLL.
.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 ;Директивы компоновщику для подключения библиотек. ;Для компоновщика LINK.EXE. includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib ELSE ;TASM 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 ;Для компоновщика TLINK32.EXE. includelib c:\tasm32\lib\import32.lib ENDIF ;------------------------------------------------ ;Сегмент данных. _DATA SEGMENT DWORD PUBLIC USE32 'DATA' TXT DB 'Ошибка динамической библиотеки',0 MS DB 'Сообщение',0 LIBR DB 'pr73_1.DLL',0 HLIB DD ? MSI 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] - Резервный параметр. ; [ЕВР+0СН] - Причина вызова. ; [ЕВР+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 MSI 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
Результат работы приложения изображен на рисунке 1:
Рис.1. Результат работы приложения
Трансляция динамической библиотеки:
ML /с /coff /DMASM pr73_1.asm LINK /SUBSYSTEM:WINDOWS /DLL /ENTRY:DLLENTRY pr73_1.obj
TASM32 /ml pr73_1.asm TLINK32 -aa -Tpd pr73_1.obj,,,,pr73_1.def Содержимое файла pr73_1.def: EXPORTS DLLP1
Трансляция программы:
ML /с /coff /DMASM pr73_2.asm LINK /SUBSYSTEM:WINDOWS pr73_2.obj
TASM32 /ml pr73_2.asm TLINK32 -aa pr73_2.obj
На следующем шаге мы продолжим изучение этого вопроса.