Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Assembler My.cpp: определяет точку входа для консольного приложения.
- //
- #include "stdafx.h"
- #include "stdlib.h"
- #include <stdio.h>
- #include <string.h>
- #include <conio.h>
- //#include <math.h>
- #include <cmath>
- void algorithm3(double mass[], double x, int n, double epsilon, double d)
- {
- int i = 1;
- int y = 0; //y=2n-1
- int two = 2;
- int one = 1;
- double result = 0.0;
- int maxsumn = 1000;
- __asm {
- mov ecx, n
- mov eax, maxsumn
- inc eax
- mov ebx, mass
- xor edx, edx
- finit // инициализация сопроцессора
- fld x
- fld epsilon // загружает точность
- fldz // команда загрузки константы 0, для последующей корректной работы, так как в регистрах может находится что угодно по-умолчанию
- fldz
- fldz
- fincstp
- bigcycle:
- repeat:
- fiadd i // st(0) = n команда сопроцессора, для суммирования регистра с целочисленным значением fadd для вещественного.
- fimul two // st(0) = 2*n команда для умножение на целочисленное значение
- fisub one // st(0) = 2*n - 1
- fist y // y = st(0) комнада сохранения значения из вершины стека в память, не сдвигая стек. для целочисленного.
- fmul st(0), st(3) // st(0) = (2*n - 1)*x
- fcos // st(0) = cos((2*n - 1)*x) трансцендентная команда st(0) = cos(st(0))
- fidiv y // st(0) = cos((2*n - 1)*x)/(2*n - 1)
- fadd st(1), st(0) // fadd приёмник, источник (приёмник = приёмник + источник)
- inc [i]
- cmp eax, i
- jbe exit1 // (n<=i)?
- fdecstp // Уменьшает указатель стека на 1
- fadd st(0), st(2)
- fabs // модуль числа st(0) = abs(st(0))
- fucom st(3) // сравнение с вершиной стека значения источника. если дописать p
- fstsw ax // С помощью команды "FSTSW AX" программа может переписать содержимое регистра состояния сопроцессора в регистр AX центрального процессора.
- sahf // содержимое регистра AH можно переписать в регистр флагов центрального процессора при помощи команды SAHF. можно использовать стандартные команды перехода je, ja, etc.
- fsub st(0), st(0) // обнуление вершины
- fincstp // Увеличивает указатель стека на 1
- jbe exit1
- fsub st(0), st(0)
- jmp repeat
- exit1:
- fsub st(0),st(0)
- fincstp
- fst QWORD PTR [ebx + edx*8] //команда сохранения значения из вершины стека в память, не сдвигая стек. для вещественного.
- fsub st(0), st(0)
- fdecstp
- fadd d
- fadd st(3), st
- fsub st(0), st(0)
- inc edx
- mov [i], 1
- loop bigcycle
- }
- }
- void algorithm4(double mass[], double x, int n, double d) {
- int two = 2;
- double y = 0.5;
- double result = 1;
- _asm {
- finit
- mov ecx, n // в ecx n = количество повторений или длина массива
- mov ebx, mass // в ebx адрес массива для результирующих значений
- xor edx, edx // в edx номер текущего жлемента массива
- fld d
- fldl2e // загрузка log 2 (e)
- bigcycle:
- fld x // загрузка x
- fidiv two // st(0) = st(0)/2
- fptan // st(0) = sin(x) st(1) = cos(x)
- fdivr st(1), st(0) // st(1) = st(1)/st(0)
- fsub st(0), st(0) //
- fadd y //
- fxch st(1) //
- fyl2x // st(0) = y(st(1)) log 2 x(st(0))
- fdiv st(0), st(1) // st(0) = y ln 2 x
- fst QWORD PTR [ebx + edx*8]
- fsub st(0), st(0)
- fadd x
- fadd st(0), st(2)
- fst x
- fsub st(0), st(0)
- fincstp
- inc edx
- loop bigcycle
- }
- }
- void algorithm12ryad(double mass[], double x, int n, double epsilon, double d)
- {
- int i = 1;
- int y = 0; //y=2n-1
- int two = 2;
- int one = 1;
- double result = 0.0;
- int maxsumn = 1000;
- __asm {
- mov ecx, n
- mov eax, maxsumn
- inc eax
- mov ebx, mass
- xor edx, edx
- xor si, si
- finit
- fld epsilon // st4 epsilon точность
- fld1 // st3 1 для хранение константы 1
- fld x // st2 x
- fld1 // st1 1 для хранения суммы n-1 членов
- fldz // st0 0 для вычислений
- fldz
- fincstp // st7 0
- bigcycle:
- sumcycle:
- fiadd i // st(0) = i команда сопроцессора, для суммирования регистра с целочисленным значением fadd для вещественного.
- fadd st(0), st(3) // st(0) = i + 1
- fmul st(0), st(2) // (i+1) x^i a i-ый элемент
- fincstp
- fchs // изменим знак суммы. таким образом получим при i чёт - (i+1)^i x сложится, а при неч вычтется в конце программы поменяем знак результата.
- fdecstp
- fadd st(1), st(0) // добавим к сумме в st(1), st(0) то есть(i+1) x^2
- inc [i] // инкремент i
- not si // флаг изменения знака для чётного количества элементов нужно изменять, для нечётного нет.
- cmp eax, i // сравнение (eax, i)
- jbe exit1 // (n<=i)?
- //fadd st(0), st(1) // копируем в st(0) сумму
- fabs // модуль числа st(0) = abs(st(0))
- fucom st(4) // сравнение с вершиной стека значения источника. если дописать p
- fstsw ax // С помощью команды "FSTSW AX" программа может переписать содержимое регистра состояния сопроцессора в регистр AX центрального процессора.
- sahf // содержимое регистра AH можно переписать в регистр флагов центрального процессора при помощи команды SAHF. можно использовать стандартные команды перехода je, ja, etc.
- fsub st(0), st(0) // обнуление вершины
- fincstp // уменьшает указатель стека на 1
- fincstp
- fmul st(0), st(0) // x*x на каждом шаге
- fdecstp
- fdecstp // увеличивает указатель стека на 1
- jbe exit1
- jmp sumcycle
- exit1:
- fincstp
- cmp si, 0
- je nochange
- fchs
- nochange:
- fst QWORD PTR [ebx + edx*8] //команда сохранения значения из вершины стека в память, не сдвигая стек. для вещественного.
- fsub st(0), st(0)
- fadd st(0), st(2)
- fincstp
- fsub st(0), st(0)
- fadd x
- fadd d
- fst x
- fdecstp
- fdecstp
- inc edx
- mov [i], 1
- xor si, si
- loop bigcycle
- }
- }
- void algorithm12func(double mass[], double x, int n, double d) {
- _asm {
- finit
- mov ecx, n // в ecx n = количество повторений или длина массива
- mov ebx, mass // в ebx адрес массива для результирующих значений
- xor edx, edx // в edx номер текущего элемента массива
- fld d // загрузка x
- fld1 // загружает единицу
- bigcycle:
- fld x // загружает x st(0) = x
- fadd st(0), st(1) // x(st(0)) = x(st(0)) + 1(st(1))
- fmul st(0), st(0) // (x+1)^2
- fdivr st(0), st(1) // st(0) = st(1)/st(0) так как есть постфикс xxxxr по умолчанию st(0) = st(0)/st(1)
- fstp QWORD PTR [ebx + edx*8] // записываем в массив получившиеся значения.
- fld x // загружаем x для прибавления шага d
- fadd st(0), st(2) // прибавляем шаг
- fstp x // fstp - выгружает данные в память, извлекая вершину стека.
- inc edx // индекс массива.
- loop bigcycle
- }
- }
- double RootMeanSquareError(double *mass1, double *mass2, int n)
- {
- double result = 0;
- _asm {
- mov ecx, n
- mov eax, mass1
- mov ebx, mass2
- xor edx, edx
- finit
- fldz
- cycle:
- fld QWORD PTR [ebx + edx*8]
- fld QWORD PTR [eax + edx*8]
- fsub st(0), st(1) // mass2[i] - mass1[i]
- fmul st(0), st(0) // (mass2[i] - mass1[i])^2
- fadd st(2), st(0) // st(2) - сумма += (mass2[i] - mass1[i])^2
- fstp result // дибильная операция по извлечению верхушки стека. дибильная, потому что ещё и записывает в память.
- fstp result
- inc edx
- loop cycle
- fild n // загружаем n
- fdivr st(0), st(1) // summ/n b помещаем в st(0)
- fsqrt // sqrt(st(0))
- fst result
- }
- return result;
- }
- inline double log2(double x)
- {
- static const double xxx = 1.0/log(2.0);
- return log(x)*xxx;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- int leng = 14;
- double *mass1 = new double[leng];
- double *mass2 = new double[leng];
- double x = 0.120796;
- double epsilon = 0.05;
- double step = 0.05;
- while (1)
- {
- printf("n = ");
- scanf("%i", &leng);
- printf("\nx = ");
- scanf("%f", &x);
- printf("\nepsilon = ");
- scanf("%f", &epsilon);
- printf("\nstep = ");
- scanf("%f", &step);
- algorithm12func(mass2, x, leng, step);
- algorithm12ryad(mass1, x, leng, epsilon, step);
- //algorithm3(mass1, x, leng, epsilon, step);
- //algorithm4(mass2, x, leng, step);
- printf("\nYour result:\n");
- for(int i = 0; i < leng; i++)
- {
- printf("ryad(%f) - %i - %e\n", x + i*step, i+1, mass1[i]);
- printf("func(%f) - %i - %e\n\n", x + i*step, i+1, mass2[i]);
- }
- printf("RootMeanSquareError %e\n\n", RootMeanSquareError(mass1, mass2, leng)); getch();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement