Будь умным!


У вас вопросы?
У нас ответы:) SamZan.net

Тема- створення та використання динамічних бібліотеки dll за допомогою мови асемблер Мета- навчитися ство.html

Работа добавлена на сайт samzan.net:

Поможем написать учебную работу

Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 25.11.2024

Cистемне програмування

Лабораторна робота № 8.

Тема: створення та використання динамічних бібліотеки dll, за допомогою мови асемблер

Мета: навчитися створювати та використовувати динамічні бібліотеки dll за допомогою мови асемблер.

Теоретична частина

Виконавчий файл містить машинний код виконуваної програми, який не обов’язково є лінійним. Зазвичай великі програми складаються з набору функцій, які зв’язані між собою викликами. На практиці дуже часто виникає ситуація коли одні і ті самі функції, що виконують одні і ті самі дії являються необхідними для роботи багатьох програм, виникає питання нащо зберігати машинний код виконання однієї і тієї самої функції у кількох екземплярах (у кількох виконавчих файлах). Для розв’язання цієї проблеми прийшли на допомогу динамічні бібліотеки dll, які дозволяють зберігати машинні коди необхідних функції і при потребі (при виклику з прогргами) загрузити цей код у оперативну пам'ять та передати його на виконання процесору.  

Отже грубо кажучи бібліотека містить скомпільований машинний код функції, який можна додати до своєї програми на етапі лікування (статичне компонування виконавчих файлів), або до грузити в оперативну пам'ять у процесі виконання програми (динамічне компонування). Розглянемо ці два способи трошки детальніше

Статичне компонування виконуваних файлів

Об'єктні файли

Під час компонування виконуваний файл будують із об'єктних файлів (object files), які створює компілятор. Об'єктний файл має заголовок, що містить розмір ділянок коду і даних, а також зсув таблиці символів; об'єктний код (інструкції і дані, згенеровані компілятором), який звичайно розділений на поіменовані ділянки (секції) залежно від призначення; таблицю символів (symbol table).

Таблиця символів — це спеціальний розділ об'єктного файлу, що містить визначення зовнішніх імен, які задають імена та відносні адреси файлових об'єктів, призначених для використання в інших файлах; зовнішні посилання (глобальні символи, що використовуються у файлі), які зазвичай містять зсув відповідної інструкції та необхідний символ.

Інформацію про зовнішні посилання називають також інформацією для налаштування адрес (relocation information).

Завантаження виконуваних файлів за статичного компонування

Виконуваний файл, отриманий внаслідок описаного раніше статичного компонування, містить усе необхідне для створення процесу. Завантаження такого файлу у пам'ять виконує окремий компонент ОС — програмний завантажувач (program loader). Він звичайно відображає виконуваний файл в адресний простір процесу (здебільшого файл відображають не як єдине ціле, а секціями, причому ділянки пам'яті для секцій виділяє також завантажувач) та ініціалізує керуючий блок процесу таким чином, щоб процес був у стані готовності до виконання.

Зазначимо, що під час відображення виконуваного файлу у пам'яті автоматично розміщають його код та ініціалізовані дані. Стек і динамічну ділянку па м'яті зазвичай створюють заново, при цьому для динамічної ділянки компілятор і компонувальник можуть тільки задати її початок, а всю інформацію із керування стеком визначає компілятор із використанням адресації щодо покажчика стека (який буде встановлено завантажувачем).

Динамічне компонування

Поняття динамічної бібліотеки

Динамічна бібліотека - набір функцій, скомпонованих разом у вигляді бінарного файлу, який може бути динамічно завантажений в адресний простір процесу, що використовує ці функції.

Динамічне завантаження (dynamic Loading) - завантаження під час виконання процесу (зазвичай реалізоване як відображення файлу бібліотеки в його адресний простір),

Динамічне компонування (dynamic linking) - компонування образу виконуваного файлу під час виконання процесу із використанням динамічних бібліотек.

Переваги використання динамічних бібліотек:

♦ Оскільки бібліотечні функції містяться в окремому файлі, розмір виконуваного файлу стає меншим і так заощаджують дуже багато дискового простору.

♦ Якщо динамічну бібліотеку використовують кілька процесів, у пам'ять завантажують лише одну її копію, після чого сторінки коду бібліотеки відображаються в адресний простір кожного з цих процесів. Це дає змогу ефективніше використовувати пам'ять.

♦ Оновлення застосування може бути зведене до встановлення нової версії динамічної бібліотеки без необхідності перекомпонування тих його частин, які не змінилися.

♦ Динамічні бібліотеки дають змогу застосуванню реалізувати динамічне завантаження  модулів на вимогу. На базі цього може бути реалізований розширюваний АРІ застосування. Для додавання нових функцій до такого АРІ стороннім розробникам достатньо буде створити і встановити нову динамічну бібліотеку.

Динамічні бібліотеки дають можливість спільно використовувати ресурси застосування (наприклад, набір піктограм), спростити локалізацію застосування, якщо всі машинно-залежні фрагменти програми, помістити в окрему DLL.

Оскільки динамічні бібліотеки є двійковими файлами, можна організувати спільну роботу бібліотек, розроблених із використанням різних мов програмування і програмних засобів, що спрощує створення застосувань на основі програмних компонентів.

Недоліки при використанні динамічних бібліотек:

♦ Використання DLL сповільнює завантаження застосування. Що більше таких бібліотек потрібно процесу, то більше файлів треба йому відобразити у свій адресний простір під час завантаження.  Для прискорення завантаження рекомендують укрупнювати DLL, об'єднуючи кілька взаємозалежних бібліотек в одну загальну.

♦ У деяких ситуаціях (наприклад, під час аварійного завантаження системи із дискети) використання спільних системних DLL неприйнятне через нестачу дискового простору для їхнього зберігання (такі системні DLL можуть займати кілька мегабайтів дискового простору, при цьому застосування часто потребують усього по кілька функцій із них).

♦ Найбільшою проблемою у використанні динамічного компонування є проблема зворотної сумісності динамічних бібліотек.

Неявне і явне зв'язування

Є два основні способи завантаження динамічних бібліотек в адресний простір процесу - неявне і явне зв'язування (implicit і explicit binding).

Неявне - основний спосіб завантаження динамічних бібліотек у сучасних ОС. При цьому бібліотеку завантажують автоматично до початку виконання застосування під час завантаження виконуваного файлу, за це відповідає завантажувач виконуваних файлів ОС. У деяких системах такий завантажувач є частиною ядра ОС, у деяких - окремим застосуванням. Список бібліотек, потрібних для завантаження, зберігають у виконуваному файлі. До переваг цього методу належать:

простота і прозорість з погляду програміста (йому не потрібно писати код завантаження бібліотек, а достатньо у налаштуваннях компонувальника вказати список потрібних бібліотек);

висока ефективність роботи процесу після початкового завантаження (усі необхідні бібліотеки до цього часу вже завантажені у його адресний простір).

Недоліком неявного зв'язування можна вважати зниження гнучкості (так, наприклад, якщо хоча б однієї з необхідних бібліотек не буде на місці, процес завантаження не обійдеться без проблем, навіть коли для виконання конкретної задачі ця бібліотека не потрібна). Крім того, збільшуються час завантаження і початковий обсяг необхідної пам'яті.

Альтернативним для неявного є явне зв'язування, коли динамічну бібліотеку завантажують в адресний простір процесу виконанням системного виклику із його коду. Після цього, використовуючи інший системний виклик, застосування отримує адресу необхідної йому функції бібліотеки і може її викликати. Після використання бібліотеку можна вилучити з пам'яті. Здебільшого неявне зв'язування зводиться до автоматичного виконання тих самих викликів, які сам програміст виконує за явного. Такий підхід вимагає від програміста додаткових зусиль, але має більшу гнучкість. Однак складність реалізації призводить до того, що його використовують лише тоді, коли застосуванню справді потрібно завантажувати і вивантажувати додаткові бібліотеки під час виконання.

Динамічні бібліотеки та адресний простір процесу. Особливості об'єктного коду динамічних бібліотек

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

Усі функції бібліотеки стають доступними для всіх потоків цього процесу, фактично її код і дані набувають вигляду доданих до адресного простору процесу. Зазначимо, що під час відображення бібліотеки у пам'ять використовують технологію копіювання під час записування, тому кожен процес матиме свою копію стека і даних бібліотеки.

З іншого боку, для коду бібліотечної функції будуть доступні такі ресурси, як дескриптори відкритих файлів процесу і стек потоку, що викликав дану функцію. Не слід, однак, забувати про те, що під час роботи із даними потоку із коду бібліотеки потрібно виявляти обережність, зокрема, ніколи не вивільняти пам'ять, розподілену не в цій бібліотеці. Іншими словами, код бібліотек, розрахованих на використання у багато потокових застосуваннях, має бути безпечним з погляду потоків (thread-safe).

Код динамічних бібліотек звичайно зберігають у виконуваних файлах формату, стандартного для цієї ОС, але з погляду характеру цього коду є одна важлива відмінність між кодом DLL і кодом звичайних виконуваних файлів. Вона полягає в тому, що код DLL в один і той самий час повинен мати можливість завантажуватися за різними адресами. Для того щоб це було можливо, такий код потрібно робити позиційно-незалежним.

Позиційно-незалежний код завжди використовує відносну адресацію (базову адресу додають до зсуву). Базову адресу налаштовують у момент завантаження DLL в адресний простір процесу і називають також базовою адресою бібліотеки; такі адреси відрізняються для різних процесів. Зсув у цьому разі називають внутрішнім зсувом об'єкта.

Одна із функцій динамічної бібліотеки може бути позначена як її точка входу. Така функція автоматично виконуватиметься завжди, коли цю DLL відображають в адресний простір процесу (явно або неявно); у неї можна поміщати код ініціалізації структур даних бібліотеки. Багато систем дають змогу задавати також і функцію, що викличеться в разі вивантаження DLL із пам'яті.

Структура виконуваних файлів

У сучасних ОС є тенденція до спрощення процедури завантаження виконуваних файлів через наближення їхнього формату до образу процесу у пам'яті. Описати загальну структуру виконуваного файлу доволі складно, тому лише зупинимося на деяких спільних компонентах таких файлів, а потім розглянемо конкретні формати.

Оскільки виконувані файли створює компонувальник на базі об'єктних файлів, то у структурі цих файлів є багато спільного. Насамперед це стосується того, що обидва види файлів складаються з набору секцій різного призначення.

Деякі спільні елементи структури виконуваних файлів (їхній порядок і точний зміст розрізняють для різних форматів цих файлів) наведено нижче.

Насамперед виконувані файли мають заголовок. Він найчастіше містить «магічні символи», які дають змогу ОС швидко визначити його тип; базову адресу відображення виконуваного коду у пам'ять; ознаку відмінності між незалежним виконуваним файлом і DLL; адреси найважливіших елементів файлу.

Майже завжди в такі файли включають інформацію для динамічного компонувальника. Звичайно ця інформація складається зі списку імпорту, що містить інформацію про всі DLL, потрібні для виконання цього файлу (для неявного зв'язування) та списку експорту, що містить інформацію про всі функції, доступні для використання іншими виконуваними файлами.

Деякі формати виконуваних файлів використовують зовнішній динамічний завантажувач; у цьому разі всередині файлу також зберігають інформацію про його місцезнаходження.

Інформацію про всі секції файлу зберігають у списку секцій, який називають таблицею секцій (section table). Елементи цієї таблиці описують різні секції файлу.

Нарешті, у файлі розташовані самі секції, що містять дані різного призначення. Назви секцій та їхній вміст розрізняються для різних форматів, але майже завжди є секції для коду та ініціалізованих даних.

Створення dll за допомогою мови асемблер

Тепер маючи достатню кількість знань про функціонування динамічних бібліотек dll, можна приступити до розгляду практичного створення та використання цих бібліотек за допомогою мови асемблер.

Отже перш за все давайте розглянемо каркас коду  бібліотеки

  ;----------------------------------------------------------------------------

  ;                           my_dll.asm

  ;----------------------------------------------------------------------------

  .386

  .model flat,stdcall

  option casemap:none

  include \masm32\include\windows.inc

  include \masm32\include\user32.inc

  include \masm32\include\kernel32.inc

  includelib \masm32\lib\user32.lib

  includelib \masm32\lib\kernel32.lib

  .data

 

 msg db "hello it is dll function",0

  

  .code

  ;-------------------- Стертова функція ----------------------------

  DllEntry proc hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD

          mov  eax,TRUE

          ret

  DllEntry Endp

  ;------------- Тестова функція в бібліотеці ------------------

  TestFunction proc

 invoke MessageBox,NULL,addr msg,addr msg,MB_OK

 ret

  TestFunction endp

  End DllEntry

В даному коді містяться дві функції  DllEntry та TestFunction. Перша з нинх є стартовою функцією і повинна обов’язково бути присутньою в бібліотеці, при загрузці даної бібліотеки в оперативну пам'ять, операційна система автоматично створить ще один потів в межах процесу що викликав двну функції і передасть йому точку входженя вказівник саме на цю функцію.

  DllEntry proc hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD

          mov  eax,TRUE

          ret

  DllEntry Endp

Дана функція отримує 3 параметри від операційної системи:

hInstDLL – хендл модуля dll

reason – прапорець що може приймати одне із наступних значень:

  •  DLL_PROCESS_ATTACH - DLL отримує значення прапорця при першій загрузці у оперативну память
  •  DLL_PROCESS_DETACK - DLL отримує цей прапорець у мемент вигризки з оперативної памяті
  •  DLL_THREAD_ATTACK - DLL отримує даний прапорець у момент створення нового потоку.
  •  DLL_THREAD_DETACK - DLL отримує даний код у момент знищення одного із потоків

По завершенню виконання цієї функції визначається чи продовжувати роботу цієї бібліотеки (TRUE FALSE), результати вератається через eax.

Окрім стартової функції у бібліотеці можуть знаходитися і інші функції, деякі з них можу формувати інтерфейс бібліотеки, а інші бути службовими і доступними лише для функцій даної бібліотеки. Для того щоб сформувати інтерфейс бібліотеки (тобто функції які буду доступні ззовні) треба описати їх у спеціальному файлі, вміст цього файла наступний:

  LIBRARY   my_dll   // назва бібліотеки

  EXPORTS   TestFunction  // назви функцій її інтерфейсу

Тепер спробуємо скомпілювати нашу бібліотеку виконавши наступні дії:

ml.exe     /c  /coff  /Cp  my_dll.asm

link.exe   /dll  /subsystem:windows  /def:my_dll.def     my_dll.obj

В результаті ми отримуємо my_dll.lib та my_dll.dll

Створення програми що використовує dll статично  за допомогою мови асемблер

Для того щоб внести у програму інформацію про функцію, що знаходиться в dll на етапі лінкування окрім об’єктних файлів лінкеру задається також файл з розширенням lib який був отриманий в результаті компілювання бібліотеки, або можна прописати в коді асемблерної програми наступний рядок -  includelib my_dll.lib Після цього всі функції які належать до інтерфейсу даної бібліотеки стануть доступними в програмі.

  ;----------------------------------------------------------------------------

  ;                                      my_test_1.asm

  ;----------------------------------------------------------------------------

.386

.model flat,stdcall

option casemap:none

include \masm32\include\windows.inc

include \masm32\include\kernel32.inc

includelib my_dll.lib   ; підключаю бібліотеку

includelib \masm32\lib\kernel32.lib

TestFunction PROTO

.code

start:

       invoke TestFunction  ; викликаю функцію з бібліотеки

       invoke ExitProcess,NULL

end start

 ;----------------------------------------------------------------------------

Щоб скомпілювати програму необхідно виконати наступні дії:

ml.exe   /c  /coff  mt_test_1.asm

link.exe   /subsystem:windows     my_test_1.obj

В результаті буде створено виконавчий файл my_test_1.exe результатом виконання якого буде вивід повідомлення:

Створення програми що використовує dll динамічно  за допомогою мови асемблер

Для того щоб динамічно використовувати бібліотеку, необхідно загружати та вигружати її з оперативної памяті по ходу виконання програми. Для цього існують спеціальні апі функції:

LoadLibrary – функція для загрузки бібліотеки в оперативну пам'ять

GetProcAddress – функція визначення адреси функції після загрузки бібліотеки в память

FreeLibrary – функція вигризки бібліотеки з памяті

Отже використовуючи ці три функції можна побудувати програму здатну загружати, викликати функції та вигружити бібліотеку з памяті, ось код такої програми:

;----------------------------------------------------------------------------

;                                      my_test_2.asm

;----------------------------------------------------------------------------

.386

.model flat,stdcall

option casemap:none

include \masm32\include\windows.inc

include \masm32\include\user32.inc

include \masm32\include\kernel32.inc

includelib \masm32\lib\kernel32.lib

includelib \masm32\lib\user32.lib

.data

LibName db "my_dll.dll",0

FunctionName db "TestFunction",0

DllNotFound db "Cannot load library",0

AppName db "Load Library",0

FunctionNotFound db "TestFunction function not found",0

.data?

hLib dd ?

TestFunctionAddr dd ?

.code

start:

       invoke LoadLibrary,addr LibName    ; загружаю бібліотеку

       .if eax==NULL   

               invoke MessageBox,NULL,addr DllNotFound,addr AppName,MB_OK ; якщо загрузка не вдалася

       .else          

               mov hLib,eax             ; зберігаю хендел бібліотеки

               invoke GetProcAddress,hLib,addr FunctionName  ; знаходжу адресу  функції

               .if eax==NULL  

                       invoke MessageBox,NULL,addr FunctionNotFound,addr AppName,MB_OK    ; якщо не вдалося вичислити адресу

               .else

                       mov TestFunctionAddr,eax

                       call [TestFunctionAddr]    ;  викликаю функцію

               .endif

               invoke FreeLibrary,hLib    ; вигружаю бібліотеку          ; вигружаю бібліотеку

       .endif

       invoke ExitProcess,NULL

end start

;----------------------------------------------------------------------------

Для того щоб скомпілювати дану прогараму необхідно виконати наступні дії:

ml.exe   /c  /coff  mt_test_2.asm

link.exe   /subsystem:windows     my_test_2.obj

В результаті буде створено виконавчий файл my_test_2.exe в результаті виконання якого буде виведено наступне повідомлення:

Завдання:

Створити dll бібліотеку, за допомогою мови асемблер, що містить функцію згідно з варіантом, та дві прикладні програми, на мові асемблер, які використовують дану бібліотеку, з статичним та динамічним зв’язуванням, у випадку динамічного зв’язування передбачити виведення повідомлень про відсутність dll бібліотеки чи необхідної функції у ній.

Варіанти завдань:

Варіант

Опис функції

1

Знайти скільки разів заданий символ входить в рядок

2

Перевірити чи кількість буквених символів у заданому рядку не перевищує заданої кількості

3

Обрізати заданий рядок до заданого символа ти вивести його на екран

4

Перевірити чи кількість цифрових символів у заданому рядку не перевищує задану кількість

5

Замінити в заданому рядку всі символи переходу на новий рядок пробілами та вивести рядок на екран

6

Перевірити чи перший та останній символи в рядку не є пробільними

Вивести окреме повідомлення якщо перший символ пробільний, окреме якщо останній, та окреме якщо обидва.

7

Перевірити чи останній символ першого слова заданого рядка дорівнює заданому символу (важати що слова розділяються лише пробілами)

8

Порахувати кількість слів у рядку, вважаючи що слова розділені лише пробілами, кількість пробілів між словами може бути довільна

9

Перевірити чи заданий рядок завершується переходом на новий рядок

10

Визначити скільки перших символів з першого заданого рядка співпадає з відповідними їм символами другого заданого рядка, припинити пошу після знаходження першого не співпавшого символа.

11

Обчислити на скільки один з заданих рядків довший від іншого

12

Обрахувати кількість великих букв у заданому рядку

13

Перевірити чи заданий рядок не починається з переходу на новий рядок

14

Перевірити чи розмір заданого рядка не перевищує задане значеня

15

Перевірити чи перше слово в заданому рядку починається маленькою буквою

16

Перевірити чи останній символ першого слова заданого рядка є буквиним символом (важати що слова розділяються лише пробілами)

17

Перевірити чи символи в заданому рядку є лише цифровими

18

Обрахувати, який з заданих рядків коротший і вивести його не екран

19

Перевірити чи в заданому рядку нема пробілів

20

Перевірити чи перше слово в заданому рядку починається цифровим символом

21

Перевірити чи перше слово в заданому рядку починається великою буквою

22

Перевірити чи заданий рядок описує число дійсного типу (наприклад «3,14»)

23

Знайти та вивести на екран перше слово з вказаного рядка

23

Обрахувати кількість цифрових символів у заданому рядку

24

Перевірити чи останній символ першого слова заданого рядка є цифровим символом (важати що слова розділяються лише пробілами)

25

Обчислити який номер по порядку займає у заданому рядку перший найдений заданий символ.

26

Обрахувати кількість малих букв у рядку

27

Обрахувати, який з заданих рядків довший і вивести його не екран

28

Перевірити чи рядок не порожній, тобто чи містить він хоч один алфавітноцифровий символ.

29

Перевірити чи довжини заданих рядків одинакові

30




1. Требуется выяснить влияние термообработки интегральных схем при Т 24 ч на уме
2. О хлебе насущном и хлебе духовном 1988 Твердый хорошее
3. Художественная литература о Великой Отечественной войне
4. Нематериальные активы
5. Актуальність теми Судинні захворювання посідають значне місце серед хвороб спинного мозку СМ нерідко
6. тематических моделей систем защиты позволяют подойти к рассмотрению методов их реализации
7. Тема работы Социальная ответственность бизнеса и приоритетные национальные проекты в России
8. миома матки является наиболее принятым потому что даёт представление о развитии опухоли из миометрия
9. биоинженерии. В 1974 году 11 ведущих молекулярных биологов мира во главе с отцом генной инженерии американцем П.html
10. Организация пенсионного обслуживания в Пензенской области
11. Отчетность при учете основных средств
12. По условиям Островского соглашения 1392 г
13. тема оподаткування в Україні- переваги і недоліки З дисципліни- Экономическая теория
14. Контрольная работа- Конформность- сущность понятия
15. на тему- Таможенная процедура беспошлинная торговля.
16. задание Групповое задание Тесты Беседа 1 Низкий уровень
17. Доклад из АйрнМаунтин о возможности и желательности мира Перевод- Желтов А.
18. реферату- Хімія і екологіяРозділ- Екологія Хімія і екологія План 1
19. Внешняя политика России в конце XVIII века
20. Лирика Иосифа Бродского