Шаг 73.
Использование общего адресного пространства

    На этом шаге мы рассмотрим использование общего адресного пространства.

    В следующей программе представлен текст динамической библиотеки и программы, вызывающей процедуру из этой библиотеки. Здесь ничего сложного, просто мы хотели продемонстрировать, что основной процесс и динамическая библиотека используют одно и то же адресное пространство. Процесс передает адреса строк, которые находятся в блоке данных основного процесса. В свою очередь, процедура возвращает в основной процесс адрес строки, находящейся в блоке данных динамической библиотеки.

    Файл 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. Результат работы приложения

    Трансляция динамической библиотеки:

    Трансляция программы:

    На следующем шаге мы продолжим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг