Автор: lonesome TSH/Digital Daemons
Дата: .01.2003
Раздел: Низкоуровневое программирование в Windows
Обычный способ загрузки функций из DLL - статическое подключение. При старте вашей программы подключенная таким образом функция уже загружена и находится в адресном пространстве программы. С точки зрения ассемблера статическая загрузка функций происходит таким образом:
extern ИмяФункции;объявление внешней функции
...код программы
call ИмяФункции;вызов функции
...код программы
Загрузку этих функций выполняет загрузчик исполняемых файлов и производится это при старте программы. Очевидно что такой способ является самым простым, но неоптимальным:
1) Если необходимых программе функций и библиотек много, то процесс их загрузки может занять значительное время
2) Функции будут отнимать оперативную память, причем все и одновременно, хотя программе возможно они не нужны в один и тот же момент времени
3) Если какая-нибудь из необходимых библиотек отсутствует, то загрузка программы станет невозможна, т.е. таким образом невозможно реализовать, например, механизм плагинов
4) В конце концов, компоновщику при компоновке программы понадобятся .LIB файлы на каждую подключаемую библиотеку, и хотя их легко сделать из существующих DLL, но иногда просто лень :)
Недостатков статической лишена динамическая компоновка, которая происходит только тогда, когда она нужна. Выгрузить библиотеку из памяти также можно в любой момент времени.
Загрузка библиотеки происходит по вызову функции LoadLibrary, которая принимает в качестве параметра имя библиотеки. После загрузки библиотеки, адреса каждой нужной функции можно получить с помощью функции GetProcAddress, которой нужно сообщить выданный первой функцией обработчик и имя функции
В нижепреведенном примере я использовал динамическую компоновку для подключения функции printf из библиотеки CRTDLL.DLL - стандартной библиотеки Си.
extern LoadLibraryA extern GetProcAddress extern ExitProcess [segment code public use32 class='CODE'] ..start: push dword lib call LoadLibraryA mov [handle], eax ;Импортирование функции printf: push dword func_printf push eax call GetProcAddress mov [printf], eax ;адрес printf был в eax ;Импортирование функции _getch: push dword func_getch push dword [handle] call GetProcAddress mov [getch], eax ;Вызов функции printf: push dword message call [printf] ;Вызов функции getch call [getch] push dword 0 call ExitProcess lib db "crtdll.dll",0 func_printf db "printf",0 func_getch db "_getch",0 message db "An example of dynamic importing of C runtime library functions",0x0A,0x0D, "Press Any Key", 0x0A, 0x0D, 0 printf dd 0 getch dd 0 handle dd 0
Компиляция:
nasm -fobj dynamicdll.asm
Компоновка:
alink -oPE -subsys console dynamicdll.obj win32.lib