WMmail.ru - сервис почтовых рассылок

воскресенье, 17 апреля 2016 г.

RFpro.ru: Ассемблер? Это просто! Учимся программировать

 
Если выпуск не отображается, вы можете прочесть его на сайте
  
  
Курс "Профессиональный трейдинг" - бесплатно!
  

     
   RFpro.ru: Ассемблер? Это просто! Учимся программировать
  

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Коцюрбенко Алексей aka Жерар
Статус: Мастер-Эксперт
Рейтинг: 356
• повысить рейтинг »
Асмик Гаряка
Статус: Советник
Рейтинг: 118
• повысить рейтинг »
Куликов Роман Евгеньевич
Статус: 1-й класс
Рейтинг: 0
• повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска:1597
Дата выхода:17.04.2016, 14:21
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:18 / 8
Вопросов / ответов:1 / 1

Консультация # 189163: Здравствуйте! У меня возникли сложности с таким вопросом: У меня появились трудности, кто нибудь может мне помочь? Рассчитать и вывести значения выражений, при заданных пользователем значений х и а...

Консультация # 189163:

Здравствуйте! У меня возникли сложности с таким вопросом:

У меня появились трудности, кто нибудь может мне помочь?
Рассчитать и вывести значения выражений, при заданных пользователем значений х и а

Дата отправки: 11.04.2016, 20:17
Вопрос задал: MITAPRONVIK (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, MITAPRONVIK!
Держите программу. Все вычисления производятся в сопроцессоре
Есть где поломать голову :)
Вещественные числа - вещь занимательная

Код (Assembler) :: выделить код
     .model   small     .data   sEnterA   db   "Enter a = $"   ;приглашение ввести а   sEnterX   db   "Enter x = $"   ;приглашение ввести х   sY   db   "y = $"      ;вывод y   c10   dw   10      ; 10 основание системы счисления               ;числа-константы из формулы   cm15   dw   -15   c6   dw   6   c34   dw   34   c2   dw   2   c16   dw   16   c8   dw   8   c14   dw   14                 ;буфер для ввода строки-вещественного числа   max   db   64      ;размер буфера   len   db   ?      ;реальная длина   String   db   64 dup (?)   ;сама строка      sTemp   db   64 dup(?)   ;временный буфер для формирования строки-числа   dig   dw   ?      ;цифра при обмене с сопроцессором      a   dd   ?      ;числа, которые вводятся   x   dd   ?        .code         ;сегмент кода      .386         ;необходимо для команды fsin      .startup      ;инициализация сегментов для выбранной модели памяти         lea   dx, sEnterX     call   InputFloat   ;вводим x      fstp   x      ;сохраним из стека сопроцессора в переменной x         lea   dx, sEnterA     call   InputFloat   ;вводим a      fstp   a        lea   dx, sY      ;выведем строку "y = "      mov   ah, 9      int   21h        call   CalcY      ;считаем y по формуле, результат в стеке сопроцессора         call   float2str   ;преобразуем вещ число в стеке сопроцессора в строку         lea   dx, String   ;и выведем      mov   ah, 9      int   21h        mov   ah, 0      ;ждем нажатие на клавишу      int   16h     .exit   0      CalcY   proc         ;расчет по формуле      fild   Cm15      ;-15      fidiv   C6      ;-15/6         fild  C34     fld   x      ;x      fimul   C2      ;a*2      fsubp	   ;34-2x     fimul  C2	   ;(34-2x)*2     faddp	   ;-15/6 + (34-2x)*2        fld   a      ;a      fsin         ;sin(a)     fidiv   C8    ;sin(a)/8     fiadd   C16   ;16+(sin(a)/8)        fdivp        ;(-15/6 + (34-2x)*2)/(16+(sin(a)/8))       fisub    C14  ;(-15/6 + (34-2x)*2)/(16+(sin(a)/8)) - 14     ret   CalcY   endp      InputFloat   proc      ;ввод вещественного числа      push   dx      ;сохраним адрес приглашения для повторного ввода      mov   ah, 9      ;выведем строку приглашения      int   21h          lea   dx, max      ;вводим строку      mov   ah, 0ah     int   21h        lea   si, String   ;адрес строки      call   str2float   ;преобразовываем во float с проверкой синтаксиса      pushf         ;флаг С говорит о корректности строки, сохраним флажки      mov   ah, 2      mov   dl, 0dh      ;перевод на новую строку      int   21h     mov   dl, 0ah     int   21h     popf         ;восстановим флажки      pop   dx      ;восстановим (уберем из стека) адрес приглашения      jc   InputFloat   ;ошибка - на повтор ввода!      ret         ;введенное число в стеке сопроцессора   InputFloat   endp        ;Преобразование строки в вещественное число в st сопроцессора   str2float   proc      ;преобразование строки в вещественное число      fldz         ;подготовим st=0      xor   dx, dx      ;число знаков после точки = 0      xor   bx, bx      ;bl = 0/1 знак числа +/-, bh = 1/0 знак уже введен/не задан      xor   di, di      ;число введенных цифр, для контроля позиции знака   s2fNext:     lodsb         ;очередной символ      cmp   al, 0dh      ;дошли до конца?      je   s2fSign      ;учтем знак      cmp   al, '+'      ;плюс?      jne   s2f_minus     cmp   bh, 0      ;знак уже был введен?      jne   s2f_err      ;можно только раз      test   di, di      jne   s2f_err      ;знак можно писать только в первой позиции      mov   bh, 1      ;знак задан      jmp   s2fNext  s2f_minus:     cmp   al, '-'      ;минус?      jne   s2f_point     cmp   bh, 0      ;знак уже был введен?      jne   s2f_err      ;можно только раз      test   di, di      jne   s2f_err      ;знак можно писать только в первой позиции      mov   bx, 0101h   ;задаем знак - минус      jmp   s2fNext  s2f_point:     cmp   al, '.'      ;точка      jne   s2f_digit     test   dx, dx      ;точку можно задать только один раз      jne   s2f_err     jmp   s2fInc  s2f_digit:         ;проверка на цифры      cmp   al, '0'      jb   s2f_err     cmp   al, '9'      ja   s2f_err        inc   di      ;есть цифра      and   ax, 0fh      ;готовим разряд       mov   dig, ax      ; для загрузки в сопроцессор      test   dx, dx      ;если целая часть, то      je   s2fMul10   ; на умножение на 10      mov   cx, dx      ;иначе делим dx раз на 10      fild   dig      ; очередной разряд   s2fdiv:     fidiv   c10      ;делим dх раз      loop   s2fdiv     faddp         ;складываем разряд за точкой с формируемым числом   s2fInc:     inc   dx      ;для точки только увеличиваем dх      jmp   s2fNext      ;пока не дойдем до конца      s2fMul10:         ;целое число      fimul   c10      ;умножаем старое на 10      fiadd   dig      ;и прибавляем очередной разряд      jmp   s2fNext  s2fSign:         ;ввод числа закончен, учтем знак      cmp   bl, 0      ;если -      je   s2fRet     fchs         ;то меняем знак   s2fRet:     clc         ;все ок      ret   s2f_err:     stc         ;ошибочка      fstp   st      ;выкидаем из стека число      ret   str2float   endp      ;преобразование вещественного числа из st в строку по адресу String   float2str   proc      push   es      push   ds      pop   es      ;es=ds         lea   di, sTemp   ;здесь будем формировать строку      ftst         ;Проверяем число      fstsw   ax      ;флаги в ax      sahf         ;флаги в регистре флагов      jnz   f2s_notZero   ;не 0      mov   dx, 1      ;длина 1      mov   bl, 0      ;сбрасываем знак      mov   ax, '0'      ;если 0, то выводим 0      stosw      jmp   f2s_Ret      ;на выход      f2s_notZero:         ;не 0      mov   al, ' '      ; пока считаем, что положительное      jnc   f2s_sign   ;если оно отрицательное,      mov   al, '-'      ; то минус      fchs         ; и оставляем модуль числа.   f2s_sign:     stosb         ;знак числа   ; Пояснение далее пойдёт на примере.   ; ST(0) ST(1) ST(2) ST(3) ...   ; Отделим целую часть от дробной.   ; 73.25 ... что-то не наше      fld1            ;  1   73.25 ...      fld   st(1)         ; 73.25  1    73.25 ...   ; Остаток от деления на единицу даст дробную часть.      fprem            ;  0.25  1    73.25 ...   ; Если вычесть её из исходного числа, получится целая часть.      fsub   st(2), st      ;  0.25  1    73    ...      fxch   st(2)         ; 73     1     0.25 ...   ; Сначала поработаем с целой частью. Считать количество цифр будем в CX.      xor   cx, cx   ; Поделим целую часть на десять,   f2s_2:   fidiv   c10         ;  7.3   1     0.25 ...      fxch   st(1)         ;  1    7.3   0.25 ...      fld   st(1)         ;  7.3    1     7.3  0.25 ...   ; отделим дробную часть - очередную справа цифру целой части исходного числа,-      fprem            ;  0.3    1     7.3  0.25 ...   ; от чатсного оставим только целую часть      fsub   st(2), st      ;  0.3    1     7    0.25 ...   ; и сохраним цифру      fimul   c10         ;  3    1     7    0.25 ...      fistp   dig         ;  1    7     0.25 ...      inc   cx   ; в стеке.      push   dig     fxch   st(1)         ;  7    1     0.25 ...   ; Так будем повторять, пока от целой части не останется ноль.      ftst      fstsw   ax      sahf      jnz   f2s_2  ; Теперь выведем её.   f2s_3:   pop   ax   ; Вытаскиваем очередную цифру, переводим её в символ и выводим.      add   al, 30h     stosb   ; И так, пока не выведем все цифры.      loop   f2s_3           ;  0    1     0.25 ...   ; Итак, теперь возьмёмся за дробную часть, для начала проверив её существование.      fstp   st(0)         ;  1    0.25 ...      fxch   st(1)          ;  0.25  1    ...      ftst      fstsw   ax      sahf      jz   f2s_5  ; Если она всё-таки ненулевая, выведем точку      lea   ax, sTemp     mov   cx, di      sub   cx, ax      sub   cx, 63      neg   cx      mov   al, '.'      stosb   ; Помножим дробную часть на десять   f2s_4:   fimul   c10         ;  2.5    1    ...      fxch   st(1)         ;  1    2.5  ...      fld   st(1)          ;  2.5    1     2.5  ...   ; отделим целую часть - очередную слева цифру дробной части исходного числа,-      fprem            ;  0.5    1     2.5  ...   ; оставим от произведения лишь дробную часть      fsub   st(2), st      ;  0.5    1     2    ...      fxch   st(2)          ;  2    1     0.5  ...   ; сохраним полученную цифру во временной ячейке      fistp   dig         ;  1    0.5  ...   ; и сразу выведем.      mov   ax, dig     add   al, 30h     stosb   ; Теперь, если остаток дробной части ненулевой      fxch   st(1)         ;  0.5    1    ...      ftst      fstsw   ax      sahf   ; и мы вывели менее cx цифр, продолжим      loopnz  f2s_4          ;  0    1    ...   ; Итак, число выведено. Осталось убрать мусор из стека.   f2s_5:   fstp   st(0)         ;  1   ...      fstp   st(0)         ;  ...      mov   byte ptr [di], '$'   ;закроем строку знаком '$' для функции 9   ; и скопировать в буфер String не более 14 знаков      lea   si, sTemp     lea   di, String      mov   dx, 0      ;длина   f2s_6:     lodsb      stosb            ;копируем 1 байт      inc   dx         ;считаем      cmp   dx, 14         ;копируем только 14 байт !!! (если получится число                  ; с большим чем 14 байт знаков, то последние усекутся)      je   f2s_7         ;насильно закрываем '$'!      cmp   al, '$'      jne   f2s_6         ;копирование завершаем по '$'      dec   dx         ;отнимем 1 (посчитался байт '$')   f2s_7:     mov   byte ptr [di], '$'   ;закроем '$' (для случая обрезания)   f2s_Ret:     pop   es      ret   float2str   endp      end  

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 12.04.2016, 16:35

5
нет комментария
-----
Дата оценки: 12.04.2016, 17:05

Рейтинг ответа:

НЕ одобряю +2 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!

 
     Прошлые выпуски
RFpro.ru: Ассемблер? Это просто! Учимся программироватьRFpro.ru: Ассемблер? Это просто! Учимся программироватьRFpro.ru: Ассемблер? Это просто! Учимся программироватьВсе выпуски рассылки
 
 
Subscribe.Ru / АО «Интернет-Проекты» / О компании / Политика конфиденциальности

Комментариев нет:

Отправить комментарий