Advertisement
Guest User

Untitled

a guest
Jun 24th, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Assembler My.cpp: определяет точку входа для консольного приложения.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "stdlib.h"
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <conio.h>
  9. //#include <math.h>
  10. #include <cmath>
  11.  
  12.  
  13. void algorithm3(double mass[], double x, int n, double epsilon, double d)
  14. {  
  15.     int i = 1;
  16.     int y = 0; //y=2n-1
  17.     int two = 2;
  18.     int one = 1;
  19.     double result = 0.0;
  20.     int maxsumn = 1000;
  21.     __asm {
  22.         mov ecx, n
  23.         mov eax, maxsumn
  24.         inc eax
  25.         mov ebx, mass
  26.         xor edx, edx
  27.         finit              // инициализация сопроцессора
  28.         fld x
  29.         fld epsilon        // загружает точность
  30.         fldz               // команда загрузки константы 0, для последующей корректной работы, так как в регистрах может находится что угодно по-умолчанию   
  31.         fldz
  32.         fldz
  33.         fincstp
  34. bigcycle:
  35. repeat:
  36.         fiadd i             // st(0) = n         команда сопроцессора, для суммирования регистра с целочисленным значением fadd для вещественного.
  37.            
  38.         fimul two           // st(0) = 2*n       команда для умножение на целочисленное значение
  39.         fisub one           // st(0) = 2*n - 1  
  40.         fist y              // y = st(0)         комнада сохранения значения из вершины стека в память, не сдвигая стек. для целочисленного.
  41.  
  42.         fmul st(0), st(3)               // st(0) = (2*n - 1)*x
  43.         fcos                // st(0) = cos((2*n - 1)*x)  трансцендентная команда st(0) = cos(st(0))
  44.         fidiv y             // st(0) = cos((2*n - 1)*x)/(2*n - 1)
  45.        
  46.         fadd st(1), st(0)   // fadd приёмник, источник  (приёмник = приёмник + источник)
  47.  
  48.         inc [i]
  49.  
  50.         cmp eax, i
  51.         jbe exit1           // (n<=i)?
  52.  
  53.         fdecstp             // Уменьшает указатель стека на 1
  54.        
  55.         fadd st(0), st(2)
  56.         fabs                // модуль числа st(0) = abs(st(0))
  57.         fucom st(3)         // сравнение с вершиной стека значения источника.  если дописать p
  58.         fstsw   ax          // С помощью команды "FSTSW AX" программа может переписать содержимое регистра состояния сопроцессора в регистр AX центрального процессора.
  59.         sahf                // содержимое регистра AH можно переписать в регистр флагов центрального процессора при помощи команды SAHF. можно использовать стандартные команды перехода je, ja, etc.
  60.        
  61.         fsub st(0), st(0)   // обнуление вершины
  62.         fincstp             // Увеличивает указатель стека на 1
  63.         jbe exit1
  64.  
  65.         fsub st(0), st(0)
  66.        
  67.         jmp repeat
  68. exit1:
  69.         fsub st(0),st(0)
  70.         fincstp
  71.        
  72.         fst QWORD PTR [ebx + edx*8]         //команда сохранения значения из вершины стека в память, не сдвигая стек. для вещественного.
  73.        
  74.         fsub st(0), st(0)
  75.         fdecstp
  76.         fadd d
  77.         fadd st(3), st
  78.         fsub st(0), st(0)
  79.         inc edx
  80.         mov [i], 1
  81.     loop bigcycle
  82.     }
  83. }
  84.  
  85.  
  86. void algorithm4(double mass[], double x, int n, double d) {
  87.     int two = 2;
  88.     double y = 0.5;
  89.     double result = 1;
  90.     _asm {
  91.         finit
  92.         mov ecx, n          // в ecx n = количество повторений или длина массива
  93.         mov ebx, mass       // в ebx адрес массива для результирующих значений
  94.         xor edx, edx        // в edx номер текущего жлемента массива
  95.         fld d
  96.         fldl2e              // загрузка log 2 (e)
  97.     bigcycle:
  98.        
  99.        
  100.  
  101.         fld x               // загрузка x
  102.        
  103.         fidiv two           // st(0) = st(0)/2
  104.         fptan               // st(0) = sin(x) st(1) = cos(x)
  105.         fdivr st(1), st(0)  // st(1) = st(1)/st(0)
  106.         fsub st(0), st(0)   //
  107.         fadd y              //
  108.         fxch st(1)          //
  109.         fyl2x               // st(0) = y(st(1)) log 2 x(st(0))
  110.         fdiv st(0), st(1)               // st(0) = y ln 2 x
  111.  
  112.         fst QWORD PTR [ebx + edx*8]
  113.         fsub st(0), st(0)
  114.         fadd x
  115.         fadd st(0), st(2)
  116.         fst x
  117.         fsub st(0), st(0)
  118.         fincstp
  119.         inc edx
  120.         loop bigcycle
  121.     }
  122. }
  123.  
  124.  
  125. void algorithm12ryad(double mass[], double x, int n, double epsilon, double d)
  126. {  
  127.     int i = 1;
  128.     int y = 0; //y=2n-1
  129.     int two = 2;
  130.     int one = 1;
  131.     double result = 0.0;
  132.     int maxsumn = 1000;
  133.     __asm {
  134.         mov ecx, n
  135.         mov eax, maxsumn
  136.         inc eax
  137.         mov ebx, mass
  138.         xor edx, edx
  139.         xor si, si
  140.         finit
  141.         fld epsilon             // st4  epsilon точность
  142.         fld1                    // st3  1 для хранение константы 1
  143.         fld x                   // st2  x
  144.         fld1                    // st1  1 для хранения суммы n-1 членов
  145.         fldz                    // st0  0 для вычислений
  146.         fldz                   
  147.         fincstp                 // st7 0
  148. bigcycle:
  149. sumcycle:
  150.         fiadd i                 // st(0) = i         команда сопроцессора, для суммирования регистра с целочисленным значением fadd для вещественного.
  151.         fadd st(0), st(3)       // st(0) = i + 1
  152.         fmul st(0), st(2)       // (i+1) x^i  a i-ый элемент
  153.         fincstp
  154.         fchs                    // изменим знак суммы. таким образом получим при i чёт - (i+1)^i x сложится, а при неч вычтется в конце программы поменяем знак результата.
  155.         fdecstp
  156.         fadd st(1), st(0)       // добавим к сумме в st(1), st(0) то есть(i+1) x^2
  157.  
  158.         inc [i]                 // инкремент i
  159.         not si                  // флаг изменения знака для чётного количества элементов нужно изменять, для нечётного нет.
  160.         cmp eax, i              // сравнение (eax, i)
  161.         jbe exit1               // (n<=i)?
  162.        
  163.        
  164.         //fadd st(0), st(1)     // копируем в st(0) сумму
  165.         fabs                    // модуль числа st(0) = abs(st(0))
  166.         fucom st(4)             // сравнение с вершиной стека значения источника.  если дописать p
  167.         fstsw   ax              // С помощью команды "FSTSW AX" программа может переписать содержимое регистра состояния сопроцессора в регистр AX центрального процессора.
  168.         sahf                    // содержимое регистра AH можно переписать в регистр флагов центрального процессора при помощи команды SAHF. можно использовать стандартные команды перехода je, ja, etc.
  169.        
  170.         fsub st(0), st(0)       // обнуление вершины
  171.         fincstp                 // уменьшает указатель стека на 1
  172.         fincstp
  173.         fmul st(0), st(0)       // x*x на каждом шаге
  174.         fdecstp
  175.         fdecstp                 // увеличивает указатель стека на 1
  176.  
  177.         jbe exit1
  178.        
  179.         jmp sumcycle
  180. exit1:
  181.         fincstp
  182.        
  183.         cmp si, 0
  184.         je nochange
  185.         fchs
  186.         nochange:
  187.         fst QWORD PTR [ebx + edx*8]         //команда сохранения значения из вершины стека в память, не сдвигая стек. для вещественного.
  188.        
  189.         fsub st(0), st(0)
  190.         fadd st(0), st(2)
  191.         fincstp
  192.         fsub st(0), st(0)
  193.         fadd x
  194.         fadd d
  195.         fst x
  196.         fdecstp
  197.         fdecstp
  198.  
  199.         inc edx
  200.         mov [i], 1
  201.         xor si, si
  202.     loop bigcycle
  203.     }
  204. }
  205.  
  206. void algorithm12func(double mass[], double x, int n, double d) {
  207.     _asm {
  208.         finit
  209.         mov ecx, n          // в ecx n = количество повторений или длина массива
  210.         mov ebx, mass       // в ebx адрес массива для результирующих значений
  211.         xor edx, edx        // в edx номер текущего элемента массива
  212.         fld d               // загрузка x
  213.         fld1                // загружает единицу
  214.     bigcycle:
  215.         fld x               // загружает x st(0) = x
  216.         fadd st(0), st(1)   // x(st(0)) = x(st(0)) + 1(st(1))
  217.         fmul st(0), st(0)   // (x+1)^2
  218.         fdivr st(0), st(1)  // st(0) = st(1)/st(0) так как есть постфикс xxxxr по умолчанию st(0) = st(0)/st(1)
  219.  
  220.         fstp QWORD PTR [ebx + edx*8] // записываем в массив получившиеся значения.
  221.         fld x                        // загружаем x для прибавления шага d
  222.         fadd st(0), st(2)            // прибавляем шаг
  223.         fstp x                       // fstp - выгружает данные в память, извлекая вершину стека.
  224.         inc edx                      // индекс массива.
  225.         loop bigcycle
  226.     }
  227. }
  228.  
  229. double RootMeanSquareError(double *mass1, double *mass2, int n)
  230. {
  231.     double result = 0;
  232.     _asm {
  233.         mov ecx, n
  234.         mov eax, mass1
  235.         mov ebx, mass2
  236.         xor edx, edx
  237.         finit
  238.         fldz
  239. cycle:
  240.             fld QWORD PTR [ebx + edx*8]
  241.             fld QWORD PTR [eax + edx*8]
  242.             fsub st(0), st(1)               // mass2[i] - mass1[i]
  243.             fmul st(0), st(0)               // (mass2[i] - mass1[i])^2
  244.             fadd st(2), st(0)               // st(2) - сумма += (mass2[i] - mass1[i])^2
  245.             fstp result                     // дибильная операция по извлечению верхушки стека. дибильная, потому что ещё и записывает в память.
  246.             fstp result
  247.             inc edx
  248.         loop cycle
  249.         fild n                              // загружаем n
  250.         fdivr st(0), st(1)                  // summ/n b помещаем в st(0)
  251.         fsqrt                               // sqrt(st(0))
  252.         fst result
  253.     }
  254.     return result;
  255. }
  256.  
  257. inline double log2(double x)
  258. {
  259.   static const double xxx = 1.0/log(2.0);
  260.   return log(x)*xxx;
  261. }
  262.  
  263. int _tmain(int argc, _TCHAR* argv[])
  264. {
  265.     int leng = 14;
  266.     double *mass1 = new double[leng];
  267.     double *mass2 = new double[leng];
  268.     double x = 0.120796;
  269.     double epsilon = 0.05;
  270.     double step = 0.05;
  271.     while (1)
  272.     {
  273.         printf("n = ");
  274.         scanf("%i", &leng);
  275.         printf("\nx = ");
  276.         scanf("%f", &x);
  277.         printf("\nepsilon = ");
  278.         scanf("%f", &epsilon);
  279.         printf("\nstep = ");
  280.         scanf("%f", &step);
  281.         algorithm12func(mass2, x, leng, step);
  282.         algorithm12ryad(mass1, x, leng, epsilon, step);
  283.         //algorithm3(mass1, x, leng, epsilon, step);
  284.         //algorithm4(mass2, x, leng, step);
  285.         printf("\nYour result:\n");
  286.         for(int i = 0; i < leng; i++)
  287.         {
  288.             printf("ryad(%f) - %i - %e\n", x + i*step, i+1, mass1[i]);
  289.             printf("func(%f) - %i - %e\n\n", x + i*step, i+1, mass2[i]);
  290.         }
  291.         printf("RootMeanSquareError %e\n\n", RootMeanSquareError(mass1, mass2, leng)); getch();
  292.     }
  293.    
  294.     return 0;
  295. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement