Перед выходом из процедуры динамической библиотеки изменяется строка, хранящаяся в разделяемой секции памяти. При этом приложение не заканчивает своей работы. При запуске второго экземпляра приложения на экран выводится уже измененное первым приложением значение строки.
dll4. asm:
; динамическая библиотека DLL4. ASM
.386P
; плоская модель
. MODEL FLAT, stdcallcasemap: noneDLLP1
; директивы компоновщику для подключения библиотекuser32. libkernel32. libwindows. inckernel32. incuser32. inc
; - -------------------------------------------------
; сегмент данных
. data DB " В динамической библиотеке",0
MS DB "Сообщение",0
; - -------------------------------------------------
; сегмент кода
. code
; [EBP+10H]; резервный параметр
; [EBP+0CH]; причина вызова
; [EBP+8]; идентификатор DLL-модуля
DLLENTRY:
MOV EAX,1
RET 12
; - -------------------------------------------------
; адреса параметров
DLLP1 PROC EXPORT
PUSH EBPEBP,ESPMessageBox, 0, OFFSET TEXT, OFFSET MS, 0
; изменим строку, расположенную в разделяемой памяти
MOV TEXT,'И'TEXT+1,'з'TEXT+2, ' 'EBPENDPDLLENTRY
dllex4. asm:
; основной модуль DLLEX4. ASM, вызывающий
; процедуру из динамической библиотеки
.386P
; плоская модель
. MODEL FLAT, stdcall casemap: none
; директивы компоновщику для подключения библиотек
includelib user32. libkernel32. libwindows. inckernel32. incuser32. inc
; - ---------------------------------
; сегмент данных
. data DB 'Ошибка динамической библиотеки',0
MS DB 'Сообщение',0
LIBR DB 'DLL4. DLL',0
HLIB DD?DB '_DLLP1@0',0
; - ---------------------------------
; сегмент кода
. code
; [EBP+10H]; резервный параметр
; [EBP+0CH]; причина вызова
; [EBP+8]; идентификатор DLL-модуля
START:
; загрузить библиотекуLoadLibrary, OFFSET LIBREAX,0_ERRHLIB,EAX
; получить адресGetProcAddress, HLIB, OFFSET NAMEPROC EAX,0
JNE YES_NAME
; сообщение об ошибке
_ERR:MessageBox, 0, OFFSET TXT, OFFSET MS, 0_EXIT_NAME:EAXMessageBox, 0, OFFSET MS, OFFSET MS, 0
; закрыть библиотеку
; библиотека автоматически закрывается также
; при выходе из программы
invoke FreeLibrary, HLIB
; выход
_EXIT:ExitProcess, 0START
Результат работы программы:
Рисунок 4
Рисунок 5
Рисунок 6
Передача параметров
Здесь демонстрируется, что основной процесс и динамическая библиотека используют одно и тоже адресное пространство. Процесс передает адреса строк, которые находятся в блоке данных основного процесса. В свою очередь, процедура возвращает в основной процесс адрес строки, находящейся в блоке данных динамической библиотеки.
dll2. asm:
; динамическая библиотека DLL2. ASM
.386P
; плоская модель
. MODEL FLAT, stdcallcasemap: none
; - ------------------------------------------------DLLP1
; константы
; сообщения, приходящие при открытии
; динамической библиотеки
DLL_PROCESS_DETACH equ 0_PROCESS_ATTACH equ 1_THREAD_ATTACH equ 2_THREAD_DETACH equ 3
; директивы компоновщику для подключения библиотек
includelib user32. lib
includelib kernel32. libwindows. inckernel32. incuser32. inc
; - -------------------------------------------------
; сегмент данных
. data
TEXT DB "Строка в динамической библиотеке",0
; - -------------------------------------------------
; сегмент кода
. code
; [EBP+10H]; резервный параметр
; [EBP+0CH]; причина вызова
; [EBP+8]; идентификатор DLL-модуля
DLLENTRY:EAX,DWORD PTR [EBP+0CH] EAX,0
JNE D1
; закрытие библиотеки
JMP _EXIT:EAX,1 _EXIT
; открытие библиотеки
_EXIT:
MOV EAX,1
RET 12
; - --------------------
; адреса параметров
; [EBP+8]
; [EBP+0CH]PROC EXPORTEBPEBP,ESPMessageBox, 0, DWORD PTR [EBP+8], DWORD PTR [EBP+0CH], 0EBPEAX,TEXT8ENDPDLLENTRY
dllex2. asm:
; основной модуль DLLEX2. ASM, вызывающий
; процедуру из динамической библиотеки
.386P
; плоская модель
. MODEL FLAT, stdcall casemap: none
; - ------------------------------------------------
; директивы компоновщику для подключения библиотек
includelib user32. libkernel32. libwindows. inckernel32. incuser32. inc
; - ---------------------------------------------
; сегмент данных
. data DB 'Ошибка динамической библиотеки',0
MS DB 'Сообщение',0
LIBR DB 'DLL2. DLL',0
HLIB DD?
MS1 DB 'Сообщение из библиотеки',0
TEXT DB 'Строка содержится в основном модуле',0
NAMEPROC DB '_DLLP1@0',0
; - ---------------------------------------------
; сегмент кода
. code
; [EBP+10H]; резервный параметр
; [EBP+0CH]; причина вызова
; [EBP+8]; идентификатор DLL-модуля
START:
; загрузить библиотекуLoadLibrary, OFFSET LIBREAX,0_ERRHLIB,EAX
; получить адресGetProcAddress, HLIB, OFFSET NAMEPROC EAX,0
JNE YES_NAME
; сообщение об ошибке
_ERR:MessageBox, 0, OFFSET TXT, OFFSET MS, 0_EXIT_NAME:OFFSET MS1OFFSET TEXTEAXMessageBox, 0, EAX, OFFSET MS, 0
; закрыть библиотеку
invoke FreeLibrary, HLIB
; библиотека автоматически закрывается также
; при выходе из программы
; выход
_EXIT:
invoke ExitProcess, 0
END START
Результат работы программы:
Рисунок 7
Рисунок 8
Вывод
В ходе данной курсовой работы были освещены основы 32-битного программирования на языке Assembler для ОС WINDOWS.
Во всех приведённых программах для вызова API функций используется функция invoke, которая позволяет намного сократить текст программы и делает программы на языке ассемблера похожими на программы на ЯВУ
Компилятор MASM, ОС Windows 7 SP2 x64.