Advertisement
Guest User

Untitled

a guest
Jun 24th, 2017
52
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. char * algorithm1(char * input_string)  //aaa !! bb1bb cc2cc  -> aaa !! bbaaabb ccbb1bbcc
  13. {
  14.     int length = strlen(input_string);
  15.     char * output_string = new char[length];
  16.     unsigned long * word_array = new unsigned long[length];
  17.  
  18.     __asm{
  19.          xor eax, eax
  20.          mov esi,[input_string] // копируем адрес указателя в регистр esi
  21.          mov ebx, word_array    // помещаем в регистр адрес адрес word_array по тестам здесь [] не имеют никакого значения
  22.          mov [ebx], 0
  23.          mov ecx, 1
  24. cycle_1:                            // в цикле бежим по исходной строке
  25.          lodsb                  // считывает символ(байт) на который указывает регистр esi и помещает в al. увеличивает esi на 1
  26.          cmp al, 0              // сравниваем с 0. 0 - терминальный символ, конец строки в си. cmp x ,y
  27.          je exit_1              // je - если x == y. выходим из цикла.
  28.          cmp al, 47             // сравниваем с кодом символа '0'
  29.          jb less47_1            // JB   Jump if below (X < Y)   CF=1
  30.          jae above47_1          // JAE  Jump if above or equal (X >= Y) CF=0
  31.          jmp cycle_1            // безусловный переход.
  32.                                     // далее идут проверки, которые должны определять разделители как символы, коды которых принадлежат [1,47) и (57,65). остальное символы.
  33. less47_1:
  34.          jmp separator_1        // если меньше чем код символа '0' 47, то считать разделителем.
  35. above47_1:
  36.          cmp al, 57
  37.          ja above57_1           // JA   Jump if above (X > Y)   CF=0 & ZF=0
  38.          jbe symbol_1           // JBE  Jump if below or equal (X <= Y) CF=1 or ZF=1
  39. above57_1:
  40.          cmp al, 65
  41.          jae symbol_1
  42.          jb separator_1
  43.  
  44. symbol_1:
  45.          cmp ecx, 1
  46.          je local_mark_1
  47.          jne cycle_1
  48. local_mark_1:
  49.          mov [ebx], esi         // помещаем в ячейку, на которую указывает ebx (word_array), адрес начала слова
  50.          sub [ebx], 1
  51.          add ebx, 4             // увеличиваем ebx на 4 байта, т.к. адреса 32-битные.
  52.          xor ecx, ecx           // обнуляем ecx - это флаг в данном алгоритме ecx==1 - предыдущий символ - разделитель
  53.          jmp cycle_1
  54.  
  55. separator_1:
  56.          cmp ecx, 1             // сравниваем флаг с 1.
  57.          jne local_mark_2           // если != то
  58.          jmp cycle_1
  59. local_mark_2:
  60.          mov ecx, 1             // устанавливаем его в 1.
  61.          jmp cycle_1
  62. exit_1:
  63.          xor ecx, ecx
  64.          mov [ebx], ecx         // добавляем 0 адрес, как символ конца массива
  65.  
  66. // конец первого алгоритма по нахождению и выделению слов. в итоге получаем "массив" адресов, каждый из которых указывает на начало нового слова в input_string
  67.  
  68.  
  69. // вторая часть алгоритма проходит от начала каждого слова до начала следующего.
  70. // само слово переворачивает и если после слова были разделители, дописывает их после слова.
  71.  
  72.          mov ebx, word_array    // указатель на ячейку памяти, в которой хранится адрес первого слова (если оно было)
  73.          mov edi, [output_string]
  74.          mov esi, [ebx]
  75. cycle_2:
  76.          lodsb
  77.          jmp procchar
  78. charprocessed:
  79.          cmp ecx, -1
  80.          je charnotnumber
  81.          jmp procwordmas
  82. wordmasprocessed:
  83.  
  84. charnotnumber:
  85.          stosb
  86.          jmp cycle_2
  87.  
  88. procchar:
  89.          mov ecx, -1
  90.          cmp al, 0               // сравниваем с 0. 0 - терминальный символ, конец строки в си. cmp x ,y
  91.          je exit_3               // je - если x == y. выходим из цикла.
  92.          cmp al, 47              // сравниваем с кодом символа '0'
  93.          jb less47_3             // JB  Jump if below (X < Y)   CF=1
  94.          jae above47_3           // JAE Jump if above or equal (X >= Y) CF=0
  95.          jmp charprocessed       // безусловный переход.
  96.                                          // далее идут проверки, которые определяют является ли символ числом или нет
  97. less47_3:
  98.          jmp notnumber_3         // если меньше чем код символа '0' 47, то считать разделителем.
  99. above47_3:
  100.          cmp al, 57
  101.          ja notnumber_3          // JA  Jump if above (X > Y)   CF=0 & ZF=0
  102.          jbe number_3            // JBE Jump if below or equal (X < Y)  CF=1 or ZF=1
  103.  
  104. number_3:
  105.          mov ecx, eax            
  106.          sub ecx, 49
  107.          jmp charprocessed
  108.  
  109. notnumber_3:          
  110.          jmp charprocessed
  111.  
  112.  
  113. procwordmas:
  114.          push ebx
  115.          push esi
  116.          cmp ecx, 0
  117.          je aftercycle_3
  118.          cmp [ebx], 0
  119.          je endcycle_4
  120. cycle_3:
  121.          add ebx, 4
  122.          cmp [ebx], 0
  123.          je endcycle_4
  124.         loop cycle_3
  125.         aftercycle_3:
  126.  
  127.          mov esi, [ebx]
  128.         cycle_4:
  129.          lodsb
  130.          jmp chekforsymbol
  131.         endcycle_4:
  132.          pop esi
  133.          pop ebx
  134.          jmp cycle_2
  135.  
  136. chekforsymbol:
  137.          cmp al, 0                // сравниваем с 0. 0 - терминальный символ, конец строки в си. cmp x ,y
  138.          je endcycle_4            // je - если x == y. выходим из цикла.
  139.          cmp al, 47               // сравниваем с кодом символа '0'
  140.          jb less47_5              // JB Jump if below (X < Y)   CF=1
  141.          jae above47_5            // JAE    Jump if above or equal (X >= Y) CF=0
  142.          jmp endcycle_4           // безусловный переход.
  143.                                       // далее идут проверки, которые определяют является ли символ разделителем или нет
  144. less47_5:
  145.          jmp separator_5          // если меньше чем код символа '0' 47, то считать разделителем.
  146. above47_5:
  147.          cmp al, 57
  148.          ja above57_5             // JA Jump if above (X > Y)   CF=0 & ZF=0
  149.          jbe symbol_5             // JBE    Jump if below or equal (X <= Y) CF=1 or ZF=1
  150. above57_5:
  151.          cmp al, 65
  152.          jae symbol_5
  153.          jb separator_5
  154.  
  155. symbol_5:
  156.          stosb
  157.          jmp cycle_4
  158.  
  159. separator_5:
  160.          jmp endcycle_4
  161.  
  162.  
  163.  
  164. exit_3:
  165.          mov al, 0
  166.          stosb
  167.     }
  168.     return output_string;
  169. }
  170.  
  171.  
  172. void algorithm2(int * input_array, int len1, int *max, int *xmax, int *min, int *xmin) // находит минимальный и максимальный элемент в массиве и определяет количество вхождений. работает с unsigned integer
  173. {
  174.     _asm {
  175.  
  176.         //ecx - счётчик цикла
  177.         //ebx - указатель на элемент массива
  178.         //eax - max
  179.         //edx - min
  180.         //esi - xmax
  181.         //edi - xmin
  182.         mov ebx, [input_array]
  183.         mov eax, [ebx]
  184.         mov edx, [ebx]
  185.         mov esi, 1
  186.         mov edi, 1
  187.         xor ecx, ecx
  188.         dec ecx
  189.  
  190.  
  191.     cycle:
  192.         inc ecx
  193.  
  194.         cmp ecx, len1
  195.         je exit_1
  196.     checkmax:
  197.         cmp [ebx + ecx*4], eax  //a[n], max [ebx + ecx*4] - адресная арифметика. адрес ebx с смещением номер элемента * 4 байта
  198.         ja aNgreaterMax         //(a[n]>max)
  199.  
  200.     checkmin:
  201.         cmp [ebx + ecx*4], edx  //a[n], min
  202.         jb aNlessMin            //(a[n]<min)
  203.  
  204.     checkequalmax:
  205.         cmp [ebx + ecx*4], eax  //a[n], max
  206.         je aNequalMax           //(a[n]=max)
  207.  
  208.     checkequalmin:
  209.         cmp [ebx + ecx*4], edx  //a[n], min
  210.         je aNequalMin           //(a[n]=min)
  211.  
  212.         jmp cycle
  213.  
  214.     aNgreaterMax:
  215.         mov eax, [ebx + ecx*4]
  216.         mov esi, 1
  217.         jmp cycle
  218.     aNlessMin:
  219.         mov edx, [ebx + ecx*4]
  220.         mov edi, 1
  221.         jmp cycle
  222.     aNequalMax:
  223.         inc esi
  224.         jmp checkequalmin
  225.     aNequalMin:
  226.         inc edi
  227.         jmp cycle
  228.  
  229. exit_1:
  230.         mov ecx, [max]
  231.         mov [ecx], eax
  232.         mov ecx, min
  233.         mov [ecx], edx
  234.         mov ecx, xmax
  235.         mov [ecx], esi
  236.         mov ecx, xmin
  237.         mov [ecx], edi
  238.     }
  239. }
  240.  
  241.  
  242. void algorithm3(double mass[], double x, int n, double epsilon, double d) // считает сумму ряда в наборе точек cos(x) + ... + cos((2n-1)x)/(2n-1)          
  243. {  
  244.     int i = 1;
  245.     int y = 0; //y=2n-1
  246.     int two = 2;
  247.     int one = 1;
  248.     double result = 0.0;
  249.     int maxsumn = 1000;
  250.     __asm {
  251.         mov ecx, n
  252.         mov eax, maxsumn
  253.         inc eax
  254.         mov ebx, mass
  255.         xor edx, edx
  256.         finit              // инициализация сопроцессора
  257.         fld x
  258.         fld epsilon        // загружает точность
  259.         fldz               // команда загрузки константы 0, для последующей корректной работы, так как в регистрах может находится что угодно по-умолчанию   
  260.         fldz
  261.         fldz
  262.         fincstp
  263. bigcycle:
  264. repeat:
  265.         fiadd i             // st(0) = n         команда сопроцессора, для суммирования регистра с целочисленным значением fadd для вещественного.
  266.            
  267.         fimul two           // st(0) = 2*n       команда для умножение на целочисленное значение
  268.         fisub one           // st(0) = 2*n - 1  
  269.         fist y              // y = st(0)         комнада сохранения значения из вершины стека в память, не сдвигая стек. для целочисленного.
  270.  
  271.         fmul st(0), st(3)               // st(0) = (2*n - 1)*x
  272.         fcos                // st(0) = cos((2*n - 1)*x)  трансцендентная команда st(0) = cos(st(0))
  273.         fidiv y             // st(0) = cos((2*n - 1)*x)/(2*n - 1)
  274.        
  275.         fadd st(1), st(0)   // fadd приёмник, источник  (приёмник = приёмник + источник)
  276.  
  277.         inc [i]
  278.  
  279.         cmp eax, i
  280.         jbe exit1           // (n<=i)?
  281.  
  282.         fdecstp             // Уменьшает указатель стека на 1
  283.        
  284.         fadd st(0), st(2)
  285.         fabs                // модуль числа st(0) = abs(st(0))
  286.         fucom st(3)         // сравнение с вершиной стека значения источника.  если дописать p
  287.         fstsw   ax          // С помощью команды "FSTSW AX" программа может переписать содержимое регистра состояния сопроцессора в регистр AX центрального процессора.
  288.         sahf                // содержимое регистра AH можно переписать в регистр флагов центрального процессора при помощи команды SAHF. можно использовать стандартные команды перехода je, ja, etc.
  289.        
  290.         fsub st(0), st(0)   // обнуление вершины
  291.         fincstp             // Увеличивает указатель стека на 1
  292.         jbe exit1
  293.  
  294.         fsub st(0), st(0)
  295.        
  296.         jmp repeat
  297. exit1:
  298.         fsub st(0),st(0)
  299.         fincstp
  300.        
  301.         fst QWORD PTR [ebx + edx*8]         //команда сохранения значения из вершины стека в память, не сдвигая стек. для вещественного.
  302.        
  303.         fsub st(0), st(0)
  304.         fdecstp
  305.         fadd d
  306.         fadd st(3), st
  307.         fsub st(0), st(0)
  308.         inc edx
  309.         mov [i], 1
  310.     loop bigcycle
  311.     }
  312. }
  313.  
  314.  
  315. void algorithm4(double mass[], double x, int n, double d) // считает значение функции в нескольких точках 0.5ln(ctg(x/2))
  316. {
  317.     int two = 2;
  318.     double y = 0.5;
  319.     double result = 1;
  320.     _asm {
  321.         finit
  322.         mov ecx, n          // в ecx n = количество повторений или длина массива
  323.         mov ebx, mass       // в ebx адрес массива для результирующих значений
  324.         xor edx, edx        // в edx номер текущего жлемента массива
  325.         fld d
  326.         fldl2e              // загрузка log 2 (e)
  327.     bigcycle:
  328.        
  329.        
  330.  
  331.         fld x               // загрузка x
  332.        
  333.         fidiv two           // st(0) = st(0)/2
  334.         fptan               // st(0) = sin(x) st(1) = cos(x)
  335.         fdivr st(1), st(0)  // st(1) = st(1)/st(0)
  336.         fsub st(0), st(0)   //
  337.         fadd y              //
  338.         fxch st(1)          //
  339.         fyl2x               // st(0) = y(st(1)) log 2 x(st(0))
  340.         fdiv st(0), st(1)               // st(0) = y ln 2 x
  341.  
  342.         fst QWORD PTR [ebx + edx*8]
  343.         fsub st(0), st(0)
  344.         fadd x
  345.         fadd st(0), st(2)
  346.         fst x
  347.         fsub st(0), st(0)
  348.         fincstp
  349.         inc edx
  350.         loop bigcycle
  351.     }
  352. }
  353.  
  354. double RootMeanSquareError(double *mass1, double *mass2, int n) //eugen version
  355. {
  356.     _asm{
  357.        mov ecx, n
  358.        mov eax, mass1
  359.        mov ebx, mass2
  360.        finit
  361.        fldz
  362. cycle:    
  363.        fld QWORD PTR [eax + 8*ecx - 8]
  364.        fld QWORD PTR [ebx + 8*ecx - 8]
  365.        fsubp st(1), st(0)           // st(1) = mass1[i]-mass2[i] и извлекаем вершину стека (постфикс p)
  366.        fmul st(0), st(0)            // (mass1[i]-mass2[i])^2
  367.        faddp st(1), st(0)           // st(1) = st(1) + (mass1[i]-mass2[i])^2 также извлекаем вершину. st(0) теперь сумма
  368.        loop cycle
  369.  
  370.        fild n               // st(0) = n
  371.        fdivp st(1), st(0)           // делим  st(1)/st(0) - summ/n
  372.        fsqrt                            // функция возвращает значение, находящееся в st(0)
  373.     }
  374. }
  375.  
  376.  
  377. inline double log2(double x)
  378. {
  379.   static const double xxx = 1.0/log(2.0);
  380.   return log(x)*xxx;
  381. }
  382.  
  383. int _tmain(int argc, _TCHAR* argv[])
  384. {
  385.     int leng = 14;
  386.     double *mass1 = new double[leng];
  387.     double *mass2 = new double[leng];
  388.     double x = 0.120796;
  389.     double epsilon = 0.05;
  390.     double step = 0.05;
  391.     while (1)
  392.     {
  393.         printf("n = ");
  394.         scanf("%i", &leng);
  395.         printf("\nx = ");
  396.         scanf("%f", &x);
  397.         printf("\nepsilon = ");
  398.         scanf("%f", &epsilon);
  399.         printf("\nstep = ");
  400.         scanf("%f", &step);
  401.         algorithm3(mass1, x, leng, epsilon, step);
  402.         algorithm4(mass2, x, leng, step);
  403.         printf("\nYour result:\n");
  404.         for(int i = 0; i < leng; i++)
  405.         {
  406.             printf("ryad(%f) - %i - %e\n", x + i*step, i+1, mass1[i]);
  407.             printf("func(%f) - %i - %e\n\n", x + i*step, i+1, mass2[i]);
  408.         }
  409.         printf("RootMeanSquareError %e\n\n", RootMeanSquareError(mass1, mass2, leng)); getch();
  410.     }
  411.    
  412.     return 0;
  413. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement