Міністерство освіти і науки
Національний університет “Львівська політехніка”
Кафедра ЕОМ
/
Звіт
з лабораторної роботи № 4
з дисципліни: “Системне програмування”
на тему: “Обчислення елементарних функцій на математичному співпроцесорі”
Мета лабораторної роботи
Познайомитися з принципами роботи математичного співпроцесора та оволодіти навиками використання вбудованих елементарних математичних функцій та реалізації розгалужень.
Теоретичні відомості
У центральному процесорі команди умовних переходів виконуються відповідно до значень окремих бітів регістра прапорців процесора. У арифметичному співпроцесорі існують спеціальні команди порівнянь, за наслідками виконання яких, встановлюються біти кодів умов в регістрі стану:
FCOM – порівняння;
FICOM – порівняння цілих чисел;
FCOMP – порівняння дійсних чисел і вилучення зі стеку;
FICOMP – порівняння цілих чисел і вилучення зі стеку;
FCOMPP – порівняння і подвійне вилучення зі стеку (ST(0), ST(1));
FTST – порівняння операнда з нулем;
FXAM – аналіз операнда на тип числа (скінчене число, денормалізоване число, нуль, нескінченність, ...).
Індивідуальне завдання
Створити *.exe програму, яка реалізовує обчислення, заданого варіантом виразу. Вхідні дані повинні вводитися з клавіатури, як дійсні числа. Програма повинна складатися з двох модулів:
головний модуль – створюється мовою С і має забезпечити ввід необхідних даних, виклик асемблерної процедури для обчислення виразу та вивід результату обчислень;
модуль безпосередніх обчислень – здійснює всі необхідні арифметичні дії з використанням математичного співпроцесора.
Переконатися у правильності роботи кожного модуля зокрема та програми загалом.
Скласти звіт про виконану роботу з приведенням тексту програми та коментарів до неї.
Дати відповідь на контрольні запитання.
29.
Примітка: ai – елементи масиву дійсних чисел подвійної точності; c та d дійсні числа одинарної точності.
Код програми
main.cpp
#include <iostream>
#include <cmath>
#include <conio.h>
extern "C" double *calc(double *, int, float, float);
void main()
{
std::cout << "lg(25 + 2 * a[i]) / d / (c + a[i] - 1),\t\tc > d" << std::endl
<< "(c + 23 - d + 4) / (a[i] - ln(a[i] + c / d)),\tc <= d" << std::endl << std::endl;
float c, d;
std::cout << "c = ";
std::cin >> c;
do
{
std::cout << "d = ";
std::cin >> d;
} while (d == 0);
int n;
do
{
std::cout << std::endl << "Enter number of elements in the array: ";
std::cin >> n;
} while (n <= 0);
double *a = (double *)malloc(n * sizeof(double));
std::cout << std::endl;
if (c > d)
for (int i = 0; i < n; ++i)
{
do
{
std::cout << "a[" << i << "] = ";
std::cin >> a[i];
} while (25 + 2 * a[i] <= 0 || c + a[i] - 1 == 0);
}
else
for (int i = 0; i < n; ++i)
{
do
{
std::cout << "a[" << i << "] = ";
std::cin >> a[i];
} while (a[i] + c / d <= 0 || a[i] - log(a[i] + c / d) == 0);
}
double *result_asm = calc(a, n, c, d);
for (int i = 0; i < n; ++i)
{
std::cout << std::endl << "C: ";
if (c > d)
std::cout << log10(25 + 2 * a[i]) / d / (c + a[i] - 1);
else
std::cout << (c + 23 - d + 4) / (a[i] - log(a[i] + c / d));
std::cout << std::endl << "Asm: " << result_asm[i] << std::endl;
}
free(a);
free(result_asm);
_getch();
}
calc.asm
.686
.model flat, c
.data
const_1 dd 1.0
const_2 dd 2.0
const_4 dd 4.0
const_23 dd 23.0
const_25 dd 25.0
.code
extrn malloc : proc
calc proc
push ebp
mov ebp, esp
mov eax, [ebp+12]
sal eax, 3
pop ebp
push eax
call malloc
add esp, 4
mov edi, eax
push ebp
mov ebp, esp
finit
fld dword ptr [ebp+16] ; ST(0) = c
fcomp dword ptr [ebp+20] ; compare c with d
fstsw ax
sahf
mov esi, [ebp+8]
mov ecx, 0
ja c_above_d
c_less_equal_d:
fld dword ptr [ebp+16] ; ST(0) = c
fadd const_23 ; ST(0) = c + 23
fsub dword ptr [ebp+20] ; ST(0) = c + 23 - d
fadd const_4 ; ST(0) = c + 23 - d + 4
fldln2 ; ST(0) = ln(2)
fld dword ptr [ebp+16] ; ST(0) = c
fdiv dword ptr [ebp+20] ; ST(0) = c / d
fadd qword ptr [esi+ecx*8] ; ST(0) = a[i] + c / d
fyl2x ; ST(0) = ln(a[i] + c / d)
fsubr qword ptr [esi+ecx*8] ; ST(0) = a[i] - ln(a[i] + c / d)
fdiv ; ST(0) = (c + 23 - d + 4) / (a[i] - ln(a[i] + c / d))
fstp qword ptr [edi+ecx*8]
inc ecx
cmp ecx, dword ptr [ebp+12]
jl c_less_equal_d
jmp exit
c_above_d:
fldlg2 ; ST(0) = lg(2)
fld qword ptr [esi+ecx*8] ; ST(0) = a[i]
fmul const_2 ; ST(0) = 2 * a[i]
fadd const_25 ; ST(0) = 25 + 2 * a[i]
fyl2x ; ST(0) = lg(25 + 2 * a[i])
fdiv dword ptr [ebp+20] ; ST(0) = lg(25 + 2 * a[i]) / d
fld dword ptr [ebp+16] ; ST(0) = c
fadd qword ptr [esi+ecx*8] ; ST(0) = c + a[i]
fsub const_1 ; ST(0) = c + a[i] - 1
fdiv ; ST(0) = lg(25 + 2 * a[i]) / d / (c + a[i] - 1)
fstp qword ptr [edi+ecx*8]
inc ecx
cmp ecx, dword ptr [ebp+12]
jl c_above_d
exit:
mov eax, edi
pop ebp
ret
calc endp
end
Результат виконання програми
/
/
Висновок
Я познайомився з принципами роботи математичного співпроцесора та оволодів навиками використання вбудованих елементарних математичних функцій та реалізації розгалужень.