Ассемблер под Windows №18

Dynamic Link Library #3


Доброго времени суток, уважаемые подписчики.


Сегодня мы продолжим разбирать возможности динамических библиотек и создадим ещё несколько макросов для удобности написания программы. Начнём с макросов. При написании программ с большим количеством функций и большими возможностями код программы неукротимо растёт, при этом понимаемость значительно уменьшается, поэтому рано или поздно нужно принимать определённые меры по уменьшению кол-ва написанного и увеличению читаемости. Во многих случаях это привело к созданию более высоких языков программирования, нам же важно не особо откланяться от низкоуровневого программирования, иначе использовать именно ассемблер потеряет смысл, но при этом облегчить себе работу. В программах, работающих под операционной системой Windows, достаточно большую часть кода занимают многочисленные push-ы, при этом они никак не помогают понять, какое именно действие они производят, передачу параметра или сохранение регистра в стеке. Для внесения однозначности, и для упрощения написания программы, я считаю удобным использование следующего макроса:

run macro address,p1,p2,p3,p4,p5,p6,p7,p8,p9
   IFNB <p9>
   push p9
   ENDIF
   IFNB <p8>
   push p8
   ENDIF
   IFNB <p7>
   push p7
   ENDIF
   IFNB <p6>
   push p6
   ENDIF
   IFNB <p5>
   push p5
   ENDIF
   IFNB <p4>
   push p4
   ENDIF
   IFNB <p3>
   push p3
   ENDIF
   IFNB <p2>
   push p2
   ENDIF
   IFNB <p1>
   push p1
   ENDIF
   call address
endm

оператор IFNB <> проверяет наличие параметра и выполняет последующие строки, только если параметр задан. В данном случае макрос помещает до девяти операндов в стек и вызывает заданную процедуру. На практике это означает следующие преобразования:

run Exitprocess, 0 push 0
call ExitProcess
run MessageBox, hProgram, offset str1, offset str2, MB_OK push MB_OK
push offset str2
push offset str1
push hProgram
call MessageBox

Обратите внимание на обратный порядок передачи параметров, пока не буду подробно объяснять, но уверяю, так гораздо удобнее.

Теперь перейдём к библиотекам, в этом уроке я хочу показать, что динамическая библиотека может содержать не только часто используемые процедуры, но также данные и ресурсы. Для этого мы рассмотрим две программы, работающие с библиотекой dll2.dll, которая помимо кода и данных содержит в себе файл ресурсов dll2.res. Файл dll2.asm имеет следующее содержание:

.386
.model flat
.data
string1db'Строка в динамической библиотеке',0
.code
_GetDataAddress@0proc
mov eax,offset string1
ret
_GetDataAddress@0endp
_start@12:
mov eax,1
ret 12
end _start@12

Библиотека содержит одну единственную процедуру, которая в свою очередь возвращает адрес строки, находящейся в блоке данных библиотеки. Рассмотрим первую программу, dll_data.asm:

includekernel32.inc
includeuser32.inc
includedll2.inc
includemacros.inc
includedef32.inc
.386
.model flat
.data
Messagedb 'Данные из .dll',0
.code
_start:
null ebx
run GetDataAddress
run MessageBox, ebx, eax, offset message, MB_OK
run ExitProcess, ebx
end _start

После компиляции эта программа будет только выводить MessageBox со строкой, находящейся в библиотеке. Если перекомпилировать библиотеку с другой строкой, то текст MessageBox - a изменится. Ничего сложного здесь нет, но этот пример очень хорошо демонстрирует то, что сама программа и загруженные библиотеки имеют общее адресное пространство. Следующая программа, dll_res.asm, будет использовать ресурсы скомпилированные в библиотеку, она выглядит следующим образом:

includekernel32.inc
includeuser32.inc
includemacros.inc
includedef32.inc
.386
.model flat
.data
DLLdb 'dll2.dll',0
.code
_start:
null ebx
run LoadLibrary, offset dll
run DialogBoxParam, eax, 01h, ebx, offset DlgProc, ebx
run ExitProcess, ebx
DlgProcproc
cmp dword ptr [esp+08h],WM_CLOSE
je close_proc
null eax
ret 16
close_proc:
run EndDialog, dword ptr [esp+08h], 0
mov eax,1
ret 16
DlgProcendp
end _start

Я думаю что это достаточно постой в понимании пример. Единственное на что следует обратить внимание на параметры функции DialogBoxParam, певым параметром мы передаём ей handle библиотеки, так как в этот раз файл ресурсов был добавлен к библиотеке, а не к программе.


Следующие файлы доступны для скачивания:
0018asm - код обеих программ и библиотеки
0018inc - файлы дополнения
0018lib - библиотеки импорта
0018exe - скомпилированные файлы


На сегодня это всё. Если есть какие вопросы, пишите, обязательно отвечу. Пишите, Dark_Lord@RusFAQ.ru, Dark_Lord@land.ru.
Или свяжитесь со мной по ICQ, мой номер 126222874!

Сайт управляется системой uCoz