Advertisement
dar7777

Untitled

Apr 18th, 2021
562
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.15 KB | None | 0 0
  1. #include<stdio.h>
  2. #include <iostream>
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7.     double minys = 1;
  8.     double a, b, c, x, y;
  9.     double five = 5;
  10.     cout << "a = ";
  11.     cin >> a;
  12.     cout << "b = ";
  13.     cin >> b;
  14.     cout << "c = ";
  15.     cin >> c;
  16.     char m1[] = "-----------------------------\n";
  17.     char m2[] = "|      x      |      y      |\n";
  18.     char m3[] = "-----------------------------\n";
  19.     char s0[] = "| %11.3lf     | %11.3lf     |\n";
  20.     char s1[] = "| %11.3lf     | ----------- |\n";
  21.     double x1 = 0; //левая граница отрезка
  22.     double x2 = 0; //правая граница отрезка
  23.     int key;
  24.     cout << "x1 = ";
  25.     cin >> x1;
  26.     cout << "x2 = ";
  27.     cin >> x2;
  28.     double t; //шаг
  29.     cout << "t = ";
  30.     cin >> t;
  31.     _asm {
  32.         //=====Заголовок таблицы=====
  33.         lea ebx, m1
  34.         push ebx
  35.         call printf
  36.         add esp, 4
  37.         lea ebx, m2
  38.         push ebx
  39.         call printf
  40.         add esp, 4
  41.         lea ebx, m3
  42.         push ebx
  43.         call printf
  44.         add esp, 4
  45.         //=====Таблица значений функции y=====
  46.         //инициализация сопроцессора
  47.         finit
  48.         //загрузить вещественное значение в стек FPU st(0) = x1
  49.         fld x1
  50.         //Сохранить вещественное значение с извлечением из стека x = st(0) и вытолкнуть (x == x1)
  51.         //[стек пуст]
  52.         fstp x
  53.         //st(0) = 0
  54.         //загружает соответствующее константное значение в вершину стека сопроцессора
  55.         fldz
  56.         the_begin :
  57.             fld x2
  58.             //st(0) = x2
  59.             //[st(1) == 0 st(0) == x2]
  60.             fsub x
  61.             //st(0) = st(0)-x (st(0) == (x2–x))
  62.             fcomip st(0), st(1)
  63.             //st(0) сравнить с st(1) и вытолкнуть
  64.             //[st(0) == 0]
  65.             //если (x2-x)<0 (выход за правую границу),
  66.             //то переход на метку end
  67.             jb the_end
  68.  
  69.             //=====Расчет y(x)=====
  70.             //если x<5, c!=0, то y=-a*x*x-b
  71.             //если x>5, c==0, то y=(x-a)/x
  72.             // но если x==0 – деление на 0
  73.             //иначе y=-(x/c)
  74.             // но если c==0 - деление на 0
  75.             //Стратегия: если значение функции в точке x
  76.             //определено, то результат помещаем в y
  77.             //и key присваиваем 0, иначе key присваиваем 1.
  78.             //В стеке [st(0) == 0]
  79.  
  80.             //x<5, c!=0, то y=-a*x*x-b
  81.             fld five
  82.             //[st(1) == 0 st(0) == 5]
  83.             fld x
  84.             //[st(1) == 5 st(0) == x]
  85.             fcomip st(0), st(1)
  86.             //если x >= 5,
  87.             //то переход на метку Expression1
  88.             jae Expression1
  89.  
  90.             fld c
  91.             fcomip st(0), st(1)
  92.             //если c == 0, то переход на метку Expression1
  93.             je Expression1
  94.  
  95.             // -a*x*x-b
  96.             //Загрузка 0
  97.             fldz
  98.             fsub minys
  99.             fmul a
  100.             fmul x
  101.             fmul x
  102.             fsub b
  103.             //y = st(0) и вытолкнуть (y == -a*x*x-b)
  104.             fstp y
  105.             mov key, 0
  106.             //key = 0 (значение y определено)
  107.             jmp l1
  108.  
  109.             //случай x>5, c==0, y=(x-a)/x
  110.         Expression1 :
  111.             fld five
  112.             fld x
  113.             fcomip st(0), st(1)
  114.             //если x = 5,
  115.             //то переход на метку Expression2
  116.             je Expression2
  117.  
  118.             fld c
  119.             fcomip st(0), st(1)
  120.             //если c != 0,
  121.             //то переход на метку Expression2
  122.             jne Expression2
  123.  
  124.             // (x - a) / x
  125.             fld x
  126.             fcomip st(0), st(1)
  127.             je zero
  128.  
  129.             fld x
  130.             fsub a
  131.             //(st(0) == x-a)
  132.             fld x
  133.             //[st(2) == 0 st(1) == x-a st(0) == x]
  134.  
  135.             fdivp st(1), st(0)
  136.             //st(1) = st(1)/st(0) и вытолкнуть
  137.             //[st(1) == 0 st(0) == (x-a)/x]
  138.             fstp y
  139.             //y = st(0) и вытолкнуть (y == (x-a)/x)
  140.             //[st(0) == 0]
  141.             mov key, 0
  142.             //key = 0 (значение y определено)
  143.             jmp l1
  144.  
  145.             Expression2 :
  146.         fld c
  147.             fcomip st(0), st(1)
  148.             je zero
  149.             // -x / c
  150.             fldz
  151.             fsub minys
  152.             fmul x
  153.             fdiv c
  154.             fstp y
  155.             //y = st(0) и вытолкнуть (y == (-x/c))
  156.             //[st(0) == 0]
  157.             mov key, 0
  158.             //key = 0 (значение y определено)
  159.             jmp l1
  160.  
  161.             zero :
  162.         mov key, 1
  163.             //key = 1 (значение y не определено)
  164.             l1 :
  165.             //=====Вывод строки таблицы=====
  166.             // если значение функции
  167.             //в точке x определено,
  168.             //то результат лежит в y и key == 0,
  169.             //иначе key == 1
  170.             //В стеке [st(0) == 0]
  171.             cmp key, 0
  172.             //сравнить key c 0
  173.             je l5
  174.             //если равны, переход на метку l5
  175.            //~~~случай, когда y не определен (key==1)~~~
  176.             sub esp, 8
  177.             //указатель сегмента стека esp уменьшить на 8
  178.             fld x
  179.             //st(0) = x [st(1) == 0 st(0) == x]
  180.             fstp qword ptr[esp]
  181.             //st(0) (то есть x) загрузить в сегмент стека
  182.             //(в соответствии с указателем сегмента стека
  183.             //esp) и вытолкнуть [st(0) == 0]
  184.             lea eax, s1
  185.             //поместить адрес строки s1 в eax
  186.             push eax
  187.             //поместить eax (адрес s1) в сегмент стека,
  188.             //автоматически уменьшится указатель сегмента
  189.             //стека esp еще на 4 байта
  190.             call printf
  191.             //вызвать функцию printf(s1,x)
  192.             add esp, 12
  193.             //вернуть указатель сегмента стека esp в
  194.             //исходное состояние (увеличить на 12)
  195.             jmp l6
  196.             //переход на метку l6
  197.             //~~~случай, когда y определен (key==0)~~~
  198.             l5 :
  199.         sub esp, 8
  200.             //указатель сегмента стека esp уменьшить на 8
  201.             fld y
  202.             //st(0) = y [st(1) == 0 st(0) == y]
  203.             fstp qword ptr[esp]
  204.             //st(0) (то есть y) загрузить в сегмент стека
  205.             //(в соответствии с указателем сегмента стека
  206.             //esp) и вытолкнуть [st(0) == 0]
  207.             sub esp, 8
  208.             //указатель сегмента стека esp уменьшить на 8
  209.             fld x
  210.             //st(0) = x [st(1) == 0 st(0) == x]
  211.             fstp qword ptr[esp]
  212.             //st(0) (то есть x) загрузили в сегмент стека
  213.             //(в соответствии с указателем сегмента стека
  214.             //esp) и вытолкнуть [st(0) == 0]
  215.             lea eax, s0
  216.             //поместить адрес строки s0 в eax
  217.             push eax
  218.             //поместить eax (адрес s0) в сегмент стека,
  219.             //автоматически уменьшится указатель сегмента
  220.             //стека esp еще на 4 байта
  221.             call printf
  222.             //вызвать функцию printf(s0,x,y)
  223.             add esp, 20
  224.             //вернуть указатель сегмента стека esp в
  225.             //исходное состояние (увеличть на 20)
  226.             l6:
  227.         fld x
  228.             //st(0) = x
  229.             //[st(1) == 0 st(0) == x]
  230.             fadd t
  231.             //st(0) = st(0)+t (st(0) == (x+t))
  232.             fstp x
  233.             //x = st(0) и вытолкнуть
  234.             //(x увеличился на шаг t) [st(0) == 0]
  235.             jmp the_begin
  236.             //переход на метку begin
  237.             the_end :
  238.     }
  239.     return 0;
  240. }
  241.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement