Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
спз маріна на друк.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
903.68 Кб
Скачать

6 Реалізація математичної функції мовою assembler

При програмуванні математичного співпроцесора може бути використано або програмування співпроцесора для роботи з числами з фіксованою комою, або програмування співпроцесора – з числами з плаваючою комою. Число з плаваючою комою — форма представлення дійсних чисел, в якій число зберігається у формі мантиси і показника степеня. Число з плаваючою комою має фіксовану відносну точність, залежну від кількості розрядів мантиси, і змінювану абсолютну. Найбільш часто використовувані представлення затверджено в стандарті IEEE 754. Реалізація математичних операцій з числами з плаваючою комою в обчислювальних системах може бути як апаратною, так і програмною. Число з фіксованою комою - формат представлення дійсного числа в пам'яті ЕОМ у вигляді цілого числа. В даній програмі використовується програмування співпроцесора для роботи з плаваючою комою. Він має вісім регістрів, які організовані у вигляді стека (рисунок 6.1). [9]

Рисунок 6.1 – Організація стека математичного співпроцесора

Основні команди, що використовуються при програмуванні:

  • Finit – команда ініціалізації;

  • Fcom src – порівняти значення першого регістру з другим;

  • Fld src – завантажити регістр;

  • Fst dst – зберегти значення у регістр;

  • Fadd dst, src – додати до першого регістра другий;

  • Fmul dst, src – помножити перший регістр на другий і зберегти результат в першому;

  • Fdiv dst, src – поділити перший регістр на другий і зберегти результат в першому. [8]

Всі данні необхідні для обчислення, ініціалізація програми, та вивід данних здійснюється за допомогою C++. Розглянемо частину коду яка виконує обчислення коли х=24:

_asm {

Finit

Fld C; //ST(3)

Fld B; //ST(2)

Fld A; //ST(1)

Fld X; //ST(0)

Fcomi ST(0), ST(1)

jbe REZ_I;

Fcomi ST(0), ST(2)

je REZ_II;

Fcomi ST(0), ST(3)

je REZ_III;

jmp EXIT

REZ_III:

Finit;

Fld H;//ST(1)

Fld Y;//ST(0)

Fadd ST(0), ST(1)

Fst Y;

jmp EXIT

7 Створення та підключення бібліотеки dll

На відміну від виконувальних файлів формату *.EXE, динамічно підключувані бібліотеки (DLL), як правило, безпосередньо не виконуються і повідомлень не обробляють. Призначення бібліотек DLL – бути викликаними процесами (тобто програмами в стадії виконання) або іншими бібліотеками в потрібний момент. Бібліотека DLL бере участь в роботі лише тоді, коли викликається одна з її функцій. DLL (англ. Dynamic-link library — динамічно приєднувана бібліотека) — реалізовані компанією Microsoft загальні бібліотеки в ОС Windows та OS/2 (Рис. 7.1).

Рис. 7.1 – Структура динамічної бібліотеки DLL

Як правило бібліотеки мають розширення файлу *.dll, *.ocx (для бібліотек, що містять елементи керування ActiveX) або *.drv (драйвери старих версій ОС). Структура DLL така сама, як і в PE-файлів (Portable Executable) для 32-, 64-розрядних Windows, та New-Executable (NE) для 16-бітових Windows. DLL може містити код, дані та ресурси в ​​будь-якій комбінації. [5]

Саме тому більшість системних файлів Windows, які мають бути доступними для всіх прикладних та системних процесів, реалізовані у форматі DLL: KERNEL32.DLL, GDI32.DLL, USER32.DLL та інші файли. Необхідно також відмітити, що динамічні бібліотеки не обов’язково містять програмний код. Наприклад, файли шрифтів (типу *.FON) також є динамічними бібліотеками, які містять лише один ресурс – опис шрифтів.

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

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

HINSTANCE Dllasm;

Dllasm = LoadLibraryA("Dll.dll");

Опрацювання помилки завантаження DLL та повідомлення про помилку:

if (LoadLibrary("Dll.dll ") == NULL)

MessageBox("Cannot find or open file Dll.dll ");

Стандартним розширення ім’я бібліотеки вважається .dll, якщо не вказувати інше. Так як в імені файлу вказано лише його назву, то цей файл повинен знаходитись в одному каталозі з основним файлом типу *.exe. Для визначення адрес окремих функцій всередині бібліотеки використовується функція GetProcAddress():

fDll calc;

calc=(fDll)GetProcAddress(Dllasm, "Calc");

Для вивантаження бібліотеки з пам'ятті процесу використовується функція FreeLibrary().

Для створення самої бібліотеки DLL був створений новий проект типу Win32 Dynamic-Link Library та вибраний перемикач Simply DLL.

В результаті було автоматично створено файл, що містить функцію DllMain(), яка є одночасно і функцією входу, і функцією виходу:

BOOL APIENTRY DllMain( HANDLE hModule,

DWORD ul_reason_for_call,

LPVOID lpReserved )

{ return TRUE; }

Далі у файлі бібліотеки DLL описана експортована функція. Дана функція має повертати значення змінної «Y». Для цього слід функцію main() замінити на функцію, ім'я якої ми використовуємо для визначення адрес:

float Calc(float X)

Експортованій функції з головної програми передається операнди типу float.

Слід записати, що буде повернуто до основної програми:

return Y;

Ім’я експортованої функції потрібно вказати в окремому файлі визначень (файл типу *.def). Цей файл необхідно приєднати до проекту.

В текстовому редакторі в цьому файлі набрати текст файлу визначень:

LIBRARY "DLL"

DESCRIPTION 'This library has one function'

EXPORTS

calc @1

У файлі визначень вказується ім’я експортованої функції та її номер, по якому функцію теж можна викликати.

Скомпільований файл необхідно скопіювати до каталогу, в якому знаходиться основна програма. [1]

Лістинг бібліотеки наведено в Додатку Б.