Регистрация: 21.05.2019
Сообщений: 4
|
Корни уравнения через сопроцессор Ассемблера
Задача следующая:
"Вычисления с использованием математического сопроцессора.
Вычислить значения корней уравнения 0= ax^3+bx+c для интервала [x1,x2] методом деления пополам."
Нужно реализовать с применением так же языка С++.
На данный момент сделано следующее, вот только все на костылях и не до конца. Помогите, пожалуйста, как можно скорее справиться с задачей.
Код:
#include <iostream>
#include <math.h>//математическая библиотека
#include <conio.h>
using namespace std;
int Sign(double Val) {//функция сигнум
if (Val == 0.) return 0;
if (Val > 0.) return 1;
else return -1;
}
//функция сама
double function(double aa, double bb,double cc, double xx){
double res = aa*pow(xx,3) + bb*xx + cc;
return res;
}
int main()
{
setlocale(LC_ALL, "Russian");
double x1, xi, x2, eps, dx;
int a, b, c;
cout << "Введите начало отрезка: ";
cin >> x1;
cout << "Введите конец отрезка: ";
cin >> x2;
cout << "Введите требуемую точность вычислений: ";
cin >> eps;
cout << "Введите a: ";
cin >> a;
cout << "Введите b: ";
cin >> b;
cout << "Введите c: ";
cin >> c;
if (function(a,b,c,x1)==0) {
cout << "Корень уравнения: " << x1 << endl;
};
if (function(a,b,c,x2)==0) {
cout << "Корень уравнения: " << x2 << endl;
};
//ДОБАВИТЬ УСЛОВИЕ ЕСЛИ РАЗНИЦА СРАЗУ НЕ БОЛЬШЕ
while ((x2-x1)>eps)
{
dx =(x2-x1)/2;
xi =x1 + dx;
if (Sign(function(a,b,c,x1))!=Sign(function(a,b,c,xi))) {
x2 = xi;
}
else {
x1 = xi;
}
}
cout<<"Корень ->>> "<<xi<<" с точностью по y = "<< eps<<endl;
//------------------через сопроцессоры ассемлера--------------
double fx1,xi,dx,razn,x;
_asm {
//xi dd ? //место под корень уравнения
//fx1 dd ? //Значение функции от x1
//dx dd ? //Значение dx
mes1 db 'No roots! $'
mes2 db 'Roots! $'
//razn dd ?
finit //инициализация сопроцессора, его очистка
//----------------------------------------------------------------------------------------------------------------
//ЭТО РАЗУМНЕЕ ОФОРМИТЬ КАК ФУНКЦИЮ
//------первое слагаемое из функции
fld x1 //Добавили в вершину стека значение x1 (начало отрезка), ST(0)=x1
fmul ST(0),ST(0) //умножаем x1 само на себя ST(0)=x1^2, ST(1)=пусто
fld x1 //добавили в вершину x1. теперь имеем ST(0)=x1, ST(1)=x1^2
fmul ST(0), ST(1) //получаем ST(0)=x1^3, ST(1)=x1^2
// fstp znx1 //выгрузили значение вершины стека в переменную
fld a //добавили в вершину стека а. ПОлучаем ST(0)=a, ST(1)=x1^3, ST(2)=x1^2
fmul ST(0), ST(1)//получаем ST(0)=a*x1^3, ST(1)=x1^3, ST(2)=x1^2
//----второе слагаемое функции
fld b //в вершину стека помещаем b. ST(0)=b, ST(1)=a*x1^3, ST(2)=x1^3, ST(3)=x1^2
fld x1 //в вершину стека помещаем x1. ST(0)=x1, ST(1)=b, ST(2)=a*x1^3, ST(3)=x1^3, ST(4)=x1^2
fmul ST(0), ST(1) // получаем: ST(0)=x1*b, ST(1)=b, ST(2)=a*x1^3, ST(3)=x1^3, ST(4)=x1^2
fadd ST(0), ST(2) // получаем: ST(0)=a*x1^3+x1*b, ST(1)=b, ST(2)=a*x1^3, ST(3)=x1^3, ST(4)=x1^2
//----Третье слагаемое функции
fld c // получаем: ST(0)=C, ST(1)=a*x1^3+x1*b, ST(2)=b, ST(3)=a*x1^3, ST(4)=x1^3, ST(5)=x1^2
fadd ST(0), ST(1) // получаем: ST(0)=a*x1^3+x1*b+C, ST(1)=a*x1^3+x1*b, ST(2)=b, ST(3)=a*x1^3, ST(4)=x1^3, ST(5)=x1^2
fst fx1 //выталкиваем значение в переменную
//---------------------------------------------------------------------------------------------------------------------
//---далее сравниваем результат
ftst //сравниваем fx1(ST(0)) с нулем
fstsw ax // сохранить слово состояния SWR в регистре AX
//Затем значения нужных бит извлекаются и анализируются основным процессором.
sahf // "копируем" флаги C0, C2, C3 в младший байт регистра EFLAGS/FLAGS
jc j1 //если выполнилось с условием "<" то переходим по j1
jz j2 //ели равно нулю
//----реализуем цикл "пока"
cikl: //реализуем основной цикл
finit //снова очищаем стека
fld x1
fld x2 //имеем ST(0)=x2, ST(1)=x1
fsub ST(0), ST(1) //Получаем ST(0)=x2-x1, ST(1)=x1
fst razn //выталкиваем значение st(0) в переменную
fld eps //вносим значение eps в st(0)=eps, st(1)= x2-x1, st(2)=x1
fcomi razn//ST(1) //оавниваем ST(0)=eps с st(1)=x2-x1
// fstsw ax // сохранить слово состояния SWR в регистре AX
//Затем значения нужных бит извлекаются и анализируются основным процессором.
//sahf // "копируем" флаги C0, C2, C3 в младший байт регистра EFLAGS/FLAGS
jae error //если eps>=razn
jb ciklif //если eps< razn
loop cikl
//----закончился цикл
//-------------процедуры-------------
j1: //"<" 0
mov ah, 09h
mov dx, offset mes1
int 21h
jmp cikl //перешли на выход//ЗДЕСЬ ПОМЕНЯТЬ НА ПЕРЕХОД В ОСНОВНОЙ ЦИКЛ
j2: //== 0
mov ah, 09h
mov dx, offset mes2
int 21h
jmp cikl //ЗДЕСЬ ИМЕНИТЬ ПЕРЕХОД В ОСНОВНОЙ ЦИКЛ
error: //равны элементы
ciklif: //цикл их и деление пополам метод
fdiv razn,2 //razn=razn/2
fst dx
fadd x1,dx //x1=x+dx
fst xi
fld x
call funct
funct PROC //процедура расчета нашей функции
fst x//fld x1 //Добавили в вершину стека значение x1 (начало отрезка), ST(0)=x1
fmul ST(0),ST(0) //умножаем x1 само на себя ST(0)=x1^2, ST(1)=пусто
fld x //fld x1 //добавили в вершину x1. теперь имеем ST(0)=x1, ST(1)=x1^2
fmul ST(0), ST(1) //получаем ST(0)=x1^3, ST(1)=x1^2
// fstp znx1 //выгрузили значение вершины стека в переменную
fld a //добавили в вершину стека а. ПОлучаем ST(0)=a, ST(1)=x1^3, ST(2)=x1^2
fmul ST(0), ST(1)//получаем ST(0)=a*x1^3, ST(1)=x1^3, ST(2)=x1^2
//----второе слагаемое функции
fld b //в вершину стека помещаем b. ST(0)=b, ST(1)=a*x1^3, ST(2)=x1^3, ST(3)=x1^2
fld x// fld x1 //в вершину стека помещаем x1. ST(0)=x1, ST(1)=b, ST(2)=a*x1^3, ST(3)=x1^3, ST(4)=x1^2
fmul ST(0), ST(1) // получаем: ST(0)=x1*b, ST(1)=b, ST(2)=a*x1^3, ST(3)=x1^3, ST(4)=x1^2
fadd ST(0), ST(2) // получаем: ST(0)=a*x1^3+x1*b, ST(1)=b, ST(2)=a*x1^3, ST(3)=x1^3, ST(4)=x1^2
//----Третье слагаемое функции
fld c // получаем: ST(0)=C, ST(1)=a*x1^3+x1*b, ST(2)=b, ST(3)=a*x1^3, ST(4)=x1^3, ST(5)=x1^2
fadd ST(0), ST(1) // получаем: ST(0)=a*x1^3+x1*b+C, ST(1)=a*x1^3+x1*b, ST(2)=b, ST(3)=a*x1^3, ST(4)=x1^3, ST(5)=x1^2
fst fx1 //выталкиваем значение в переменную
funct ENDP
ex: mov ax, 04C00h//завершение программы
int 21h
}
cout << "\nАссемблер-->> Корень равен: " << xi<< " с точностью по y = "<< eps<<endl;;
//----------------------------------------------
getch();//для задерживания закрытия программы
return 0;
}
|