СТВОРЕННЯ DLL ТА ЇХ ВИКОРИСТАННЯ ПРИ ЯВНОМУ ЗВ’ЯЗУВАННІ НА МОВІ АСЕМБЛЕР

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
Не вказано
Кафедра:
Не вказано

Інформація про роботу

Рік:
2015
Тип роботи:
Лабораторна робота
Предмет:
Системне програмування та операційні системи

Частина тексту файла (без зображень, графіків і формул):

Міністерство освіти, науки, молоді та спорту України Національний університет “Львівська політехніка” Кафедра ****** Звіт до лабораторної роботи №6 з дисципліни: «Системне програмування» на тему: “СТВОРЕННЯ DLL ТА ЇХ ВИКОРИСТАННЯ ПРИ ЯВНОМУ ЗВ’ЯЗУВАННІ НА МОВІ АСЕМБЛЕР” Підготував: *********** Прийняв: *********** Львів 2015 Мета: Ознайомитись з технологією та оволодіти навиками створення та використання бібліотек динамічного компонування з використанням явного зв’язування на мові Асемблера. ТЕОРЕТИЧНІ ВІДОМОСТІ Динамічне компонування образу задачі в процесі її виконання надає ряд переваг розробникам програмного забезпечення в порівнянні зі статичним копонуванням. До переваг відносяться: - зменшується розмір виконуваного файлу; - у пам’ять завантажують лише одну копію динамічноїбібліотеки; - оновлення бібліотек не веде до перекомпонування застосування; - реалізовується динамічне завантаження модулів на вимогу; - можливість спільно використовувати ресурси застосування; - можна організувати спільну роботу бібліотек, розроблених із використанням різних мов програмування. Однак воно не позбавлене недоліків: - сповільнює завантаження застосування; - не ефективно використовуватися зовнішня пам’ять; - проблема є зворотної сумісності; - ускладнюється процес інсталювання програмного застосування. Однак грамонто володіючи технологією створення та підтримки динамічних бібліотек можне зменшити вплив деяких з цих недоліків на програмний продукт, а деякі подолати. Можливі 2 способи використання динамічних бібліотек. Вони називаються “явним” та “неявним” зв’язуванням. “Явне” та “неявне” зв’язування бібліотеки з програмою мають суттєві відмінності в процесі написання та компіляції програми. Неявне зв’язування бібліотеки з програмою (Load-time dynamic linking) полягає в тому, що бібліотека (яка міститься у файлі з розширенням .dll) завантажується в пам’ять в момент завантаження програми. До переваг “неявного” зв’язування в порівнянні з “явним” відноситься: - простота програмування. Розробник не вникає в проблеми зв’язування назв функцій з адресами за якими завантажена їх реалізація; - прогнозованість поведінки застосування. Якщо застосування успішно завантажено, то усі проблеми перехрестних зв’язків уже вирішено; Однак у “неявного” зв’язування існує ряд недоліків: - при відсутності бодай однієї з бібліотек при запуску програми відбудеться збій та припинення виконання програми; - значні затрати часу на завантаження та старт застосування, пов’язані з необхідністю завантаження усіх динамічних бібліотек; - відсутня можливість вивантаження непотрібних в даний час динамічних бібліотек; - на час компонування необхідно мати додаткові файли з прототипами функцій та бібліотеку імпорту (.lib). Отже, основними перевагами “явного” зв’язування, є можливість тонко керувати процесами завантаження та вивантаження динамічних бібліотек, а отже і використовуваною пам’яттю, хоча і за рахунок складності програмування. “Явне” зв’язування бібліотеки з програмою (Run-time dynamic linking) полягає в тому, що бібліотека (яка міститься у файлі з розширенням .dll) завантажується в пам’ять в момент часу, що визначається розробником, за допомогою виклику АРІ функцій LoadLibrary або LoadLibraryEX. При успішному виконанні функція повертає адресу точки входу. При відсутності бібліотеки, яку необхідно завантажити, або при помилках її завантаження функція поверне NULL, а сама програма, може продовжити виконання. Звичайно, якщо функції, що містяться у відсутній бібліотеці не є критичними для її подальшої роботи. Для виклику бібліотечної функції необхідно оголосити вказівник на функцію, та присвоїти йому адресу бібліотечної функції. Для цього необхідно використати АРІ функцію GetProcAddress, яка повертає адресу вказаної їй у параметрі бібліотечної функції. Після завершення роботи з функціями бібліотек, програмі необхідно вивантажити бібліотеки за допомогою функції FreeLibrary. Для успішної компіляції необхідно мати лише dll файл бібліотеки. Запуск програми відбудеться навіть за відсутності бібліотечного файлу, оскільки його наявність при використанні “явного” зв’язування не перевіряється. Завдання Ввести два рядки тексту, вилучити з довшого рядка всі входження коротшого рядка. Вивести новий рядок на екран. На першому етапі створюємо бібліотеку (файли lab07.dll і lab07.lib) засобами MSVS. Для цього створюємо проект типу DLL, в якому два файли: lab07.def i lab07.asm: //lab07.def LIBRARY Lab07 EXPORTS RFunc //lab07.asm .586 .model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\macros\macros.asm ; підключення файлів з форматами прототипів виклику функцій include \masm32\include\masm32.inc include \masm32\include\gdi32.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\advapi32.inc ; підключення заголовків бібліотек експортованих функцій includelib \masm32\lib\masm32.lib includelib \masm32\lib\gdi32.lib includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\advapi32.lib .data titul db "KhomitsVM @ Labwork #7, asm dll function.", 0 isFound db "Substring found in string!",0 isRez db "Rezult: ",0 lpSrc dword 256 dup(?),0 lpPattern dword 256 dup(?),0 str1 dword 256 dup(?),0 str2 dword 256 dup(?),0 BaseLen DWORD 0 SubLen DWORD 0 str1len dword 0 str2len dword 0 nl DB 0AH,0DH,0 .code DllEntry PROC hInstDLL: DWORD, reason: DWORD, reserved:DWORD mov eax,1 ret DllEntry ENDP RFunc PROC pusha invoke StdOut,addr titul invoke StdOut,ADDR nl invoke StdOut,chr$("Input original string: ") invoke StdIn,addr lpSrc,LengthOf lpSrc invoke StdOut,chr$("Input replaced string: ") invoke StdIn,addr lpPattern,LengthOf lpPattern cld ;обчислення довжин введених рядків символів lea edi, lpSrc mov esi,edi mov ecx, 0FFFFFFFFH xor al,al repne scasb sub edi,esi dec edi mov BaseLen, edi lea edi, lpPattern mov esi,edi mov ecx, 0FFFFFFFFH xor al,al repne scasb sub edi, esi dec edi mov SubLen, edi ;порівняння довжин рядків mov ebx,SubLen cmp BaseLen,ebx jb s2s1 ;копіюємо довший рядок в змінну str1(а його довжину в str1len), ;аналогічно для коротшого рядка str2 (str2len) cld mov ecx,BaseLen lea esi,lpSrc lea edi,str1 rep movsb mov ecx,SubLen lea esi,lpPattern lea edi,str2 rep movsb mov ebx,BaseLen mov str1len,ebx mov ebx,SubLen mov str2len,ebx mov edi,str2len jmp s1s2 s2s1: cld mov ecx,SubLen lea esi,lpPattern lea edi,str1 rep movsb mov ecx,BaseLen lea esi,lpSrc lea edi,str2 rep movsb mov ebx,SubLen mov str1len,ebx mov ebx,BaseLen mov str2len,ebx mov edi,str2len ;завершення блоку визначення довшого і коротшого рядків ;їхні дані відповідно записані в str1 (str1len) i str2 (str2len) s1s2: mov ebx,0 lea esi, str1 mainloop: lea edi, str2 .if ebx==str1len jmp toexit .endif push esi cld mov ecx, [str2len] repe cmpsb jne next invoke StdOut,addr isFound invoke StdOut,ADDR nl mov edi ,esi sub edi, str2len mov edx,str1len sub edx, ebx sub edx,str2len mov ecx,edx inc ecx rep movsb next: pop esi inc esi inc ebx jmp mainloop toexit: invoke StdOut,addr isRez invoke StdOut,addr str1 invoke StdOut,ADDR nl invoke Sleep,10000 popa ret RFunc ENDP End DllEntry Після компіляції отримаємо бібліотеку (файли lab07.dll і lab07.lib, яка містить одну функцію: RFunc (без аргументів), яка вилучає з одного рядка інший (з довшого коротший). На другому етапі будуємо проект консольного типу, пишемо програму, яка дозволяє викликати функцію RFunc з допомогою засобів явного звязування з бібліотеки lab07.dll (використавши lab07.lib). Для цього два файли, lab07.dll і lab07.lib, розміщуємо в папці основного проекту. Код програми: //laba6.cpp .586 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\macros\macros.asm ; підключення файлів з форматами прототипів виклику функцій include c:\masm32\include\masm32.inc include c:\masm32\include\gdi32.inc include c:\masm32\include\user32.inc include c:\masm32\include\kernel32.inc include c:\masm32\include\advapi32.inc ; підключення заголовків бібліотек експортованих функцій includelib c:\masm32\lib\masm32.lib includelib c:\masm32\lib\gdi32.lib includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib includelib c:\masm32\lib\advapi32.lib .data LibName db "Lab07.dll",0 FunctionName db "RFunc",0 DllNotFound db "Cannot load library",0 AppName db "Load explisit library",0 NotFound db "StrFunct function not found",0 .data? hLib dd ? RFuncAddr dd ? .code start: invoke LoadLibrary, addr LibName .if eax==NULL invoke MessageBoxA, NULL, addr DllNotFound, addr AppName, MB_OK .else mov hLib, eax invoke GetProcAddress, hLib, addr FunctionName .if eax == NULL invoke MessageBoxA, NULL,addr NotFound, addr AppName, MB_OK .else mov RFuncAddr,eax call [RFuncAddr] .endif invoke FreeLibrary,hLib .endif invoke ExitProcess, NULL end start Детальний опис роботи коду В Асемблері рядки є послідовностями байтів, які можуть або представляти, або не представляти ASCII-символи. Рядкові команди діляться на три групи: - команди пересилки рядків - команди перевірки рядків - команди префікса повтору. Для вводу рядків використовуємо стандартні засоби MASM invoke StdOut, invoke StdIn. Далі функція обчислює довжини введених рядків та порівнює їх. За результатами перевірки вибираємо довший рядок і в ньому здійснюємо пошук вкладення коротшого рядка. Якщо вкладення є, то шляхом використання рядкових команд дописуємо «хвіст» рядка в позицію, де починалось вкладення. Таким чином отримуємо ефект видалення коротшого рядка з довшого. У рядку, що отримали після видалення, знову здійнюємо пошук вкладення коротшого рядка. Процес повторюємо до проходження всіх символів рядка (для оптимізації роботи можна було б проходити не всі символи – використати момент, що залишок довшого рядка для пошуку не може бути коротшим за короткий рядок). Результат роботи виводиться функцією в консоль. Для роботи використано наступні команди обробки рядків: lea - запис ефективної адреси в регістр; repne scasb - сканування рядка, поки не нуль; rep movsb – копіювання ланцюжка (рядка) символів, допоки в регістрі ecx не нуль; repe cmpsb – команда порівняння двох рядків, допоки в регістрі ecx не нуль. Префікси rep, repe, repne – означають повтор рядкових команд, допоки в регістрі ecx не нуль. Попередньо в регістер ecx заноситься необхідне число повторів (згідно логіки програми). Після завершення роботи бібліотечної функції повертаємось в основну програму і завершуємо роботу. Результат виконання програми: Варіант, коли перший введений рядок довший за другий / Варіант, коли другий введений рядок довший за перший / Висновок: на цій лабораторній роботі я навчилась створювати бібліотеки та використовувати виклики функцій з цих бібліотек при явному звязуванні.
Антиботан аватар за замовчуванням

05.03.2017 21:03-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!