Вычисление выражения по формуле - Assembler (223260)

Узнай цену своей работы

Формулировка задачи:

Необходимо посчитать след. формулу: Вот программа, которую собрал из учебника:
Листинг программы
  1. title prim
  2. assume cs:cod, ds:d, ss:s
  3. s segment stack
  4. dw 128 dup (?)
  5. s ends
  6. d segment
  7. ;резервируем области под переменные a, b, c
  8. a dw ?
  9. b dw ?
  10. c dw ?
  11. ;размещаем строки подсказки для ввода переменных
  12. msga db ‘Введите a:$
  13. msgb db ‘Введите b:$
  14. msgc db ‘Введите c:$
  15. ;размещаем строки сообщения об ошибках
  16. err1 db ‘Деление на ноль (первая дробь)$
  17. err2 db ‘Деление на ноль (вторая дробь)$
  18. ;описываем данные для процедур ввода и вывода целых чисел
  19. .
  20. .
  21. .
  22. d ends
  23. c od segment
  24. ;описываем процедуры ввода и вывода целых чисел
  25. cr = 0dh ;cr присваиваем значение кода символа
  26. ;возврата каретки (клавиши «Enter»)
  27. lf = 0ah ;lf присваиваем значение кода символа
  28. ;перевода строки
  29. IntegerIn proc
  30. start: mov ah,0ah ;функцией 0a вводим строку
  31. ;символов и размещаем ее в
  32. ;области string
  33. lea dx,string
  34. int 21h
  35. xor ax,ax ;обнуляем ax, в котором
  36. ;будем формировать число
  37. lea si,string+2 ;устанавливаем si на
  38. ;первый символ введенной
  39. ;строки
  40. mov negflag,ax ;обнуляем флаг
  41. ;отрицательности числа
  42. ;(предполагаем, что оно
  43. ;будет неотрицательным)
  44. cmp byte ptr [si],'-';первый символ это
  45. ;минус?
  46. jne m2 ;если нет на m2
  47. not negflag ;отмечаем, что число
  48. ;отрицательное
  49. ;(negflag не равен 0)
  50. inc si ;продвигаем si со
  51. ;знака числа к первой
  52. ;цифре
  53. jmp m ;прыгаем на разбор
  54. ;строки цифр
  55. m2: cmp byte ptr [si],'+';первый символ это
  56. ;плюс?
  57. jne m ;если нет на m
  58. inc si ;продвигаем si со
  59. ;знака числа к первой
  60. ;цифре
  61. ;анализируем текущий символ
  62. m: cmp byte ptr [si],cr ;если это cr строка
  63. ;закончилась, выходим
  64. ;из цикла разбора
  65. ;символов
  66. je ex1
  67. cmp byte ptr [si],'0';если код символа
  68. ;меньше кода '0'
  69. ;это не цифра
  70. jb err ;прыгаем на метку err
  71. cmp byte ptr [si],'9';если код символа
  72. ;больше кода '9'
  73. ;это не цифра
  74. ja err ;прыгаем на метку err
  75. mov bx,10 ;домножаем полученное
  76. ;число на основание
  77. ;системы счисления
  78. mul bx
  79. sub byte ptr [si],'0';вычитаем код символа
  80. ;'0' (получаем
  81. ;очередную цифру)
  82. add al,[si] ;добавляем цифру к
  83. ;числу
  84. adc ah,0
  85. inc si ;продвигаем si к
  86. ;следующему символу
  87. jmp m ;организуем цикл
  88. ;функцией 09 выводим сообщение об ошибке
  89. err: lea dx,errmsg
  90. mov ah,9
  91. int 21h
  92. jmp start ;повторяем ввод
  93. ex1: cmp negflag,0 ;число положительное?
  94. je ex ;если да выходим
  95. neg ax ;меняем знак числа
  96. ex: ret
  97. IntegerIn endp
  98. IntegerOut proc
  99. xor cx,cx ;обнуляем счетчик цифр
  100. mov bx,10 bx помещаем делитель
  101. cmp ax,0 ;проверяем знак числа
  102. jge m ;если неотрицательное на m
  103. neg ax ;иначе меняем знак числа
  104. pushax ;сохраняем число перед вызовом
  105. ;функции, использующей ax
  106. mov ah,2 ;функцией 02 выводим знак '-'
  107. mov dl,'-'
  108. int 21h
  109. pop ax ;восстанавливаем число в ax
  110. m: inc cx ;считаем количество
  111. ;получающихся цифр
  112. xor dx,dx ;преобразуем делимое к 32
  113. ;разрядам
  114. div bx ;получаем очередную цифру
  115. pushdx ;сохраняем ее в стеке
  116. or ax,ax ;проверяем есть ли еще цифры
  117. jnz m ;если да на метку m
  118. ;при выходе из цикла в стеке лежат цифры, в cx их
  119. ;количество
  120. m1: pop dx ;извлекаем цифру из стека
  121. add dx,'0' ;преобразуем в код символа
  122. mov ah,2 ;функцией 02 выводим на экран
  123. int 21h
  124. loopm1 ;повторяем cx раз
  125. ret ;возвращаемся из процедуры
  126. IntegerOut endp
  127. ;устанавливаем ds на сегмент данных
  128. string db 255, 0, 255 dup (?)
  129. errmsg db 'Недопустимый символ, можно'
  130. db 'использовать только цифры',cr,lf,'$'
  131. start: mov ax,d
  132. mov ds,ax ;вводим значение переменныой a
  133. Mov ah,09 ;выводим строку подсказку для a
  134. Lea dx,msga
  135. Int 21h
  136. Call IntegerIn ;вводим число
  137. Mov a,ax ;помещаем его в область a
  138. ;вводим значение переменныой b
  139. Mov ah,09 ;выводим строку подсказку для b
  140. Lea dx,msgb
  141. Int 21h
  142. Call IntegerIn ;вводим число
  143. Mov b,ax ;помещаем его в область b
  144. ;вводим значение переменныой c
  145. Mov ah,09 ;выводим строку подсказку для c
  146. Lea dx,msgc
  147. Int 21h
  148. Call IntegerIn ;вводим число
  149. Mov c,ax ;помещаем его в область c
  150. ;проверяем знаменатели на равенство 0
  151. Cmp c,0 ;проверяем первый знаменатель
  152. Jnz m ;если не 0 на m
  153. Mov ah,09 ;выводим сообщение об ошибке
  154. Lea dx,err1
  155. Int 21h
  156. Jmp err ;выходим
  157. m: Mov ax,b ;считаем второй знаменатель
  158. Add ax,c
  159. Jnz m1 ; если не 0 на m1
  160. Mov ah,09 ;выводим сообщение об ошибке
  161. Lea dx,err2
  162. Int 21h
  163. Jmp err ;выходим
  164. ;рассчитываем значение выражения
  165. m1: Mov bx,ax ;помещаем второй знаменатель в bx
  166. Mov ax,a ;считаем второй числитель
  167. Imul ax
  168. Mov cx,3
  169. Imul cx
  170. Idiv bx ;считаем значение второй дроби
  171. Push ax ;сохраняем его в стеке
  172. Mov ax,a ;считаем первый числитель
  173. Add ax,b
  174. Mov bx,c ;считаем значение первой дроби
  175. Cwd
  176. Idiv bx
  177. Pop bx ;извлекаем из стека значение второй
  178. ;дроби
  179. Sub ax,bx ;вычитаем
  180. call IntegerOut ;выводим результат
  181. ;завершаем работу программы
  182. mov ax,4c00h кодом завершения 0 без ошибок
  183. int 21h
  184. err: mov ax,4cffh кодом завершения 0ffh (-1) с ошибкой
  185. int 21h
  186. c od ends
  187. end start

Решение задачи: «Вычисление выражения по формуле»

textual
Листинг программы
  1.         title prim
  2.         assume cs:cod, ds:d, ss:s
  3. LOCALS
  4. s        segment stack
  5.         dw 128 dup (?)
  6. s        ends
  7. d        segment
  8. ;резервируем области под переменные a, b, c
  9. a        dw ?
  10. b        dw ?
  11. y        dw ?
  12. ;размещаем строки подсказки для ввода переменных
  13. msga         db 'Введите a:$'
  14. msgb         db 'Введите b:$'
  15. ;размещаем строки сообщения об ошибках
  16. err1         db 'Деление на ноль (первая дробь)$'
  17. err2         db 'Деление на ноль (вторая дробь)$'
  18. ;описываем данные для процедур ввода и вывода целых чисел
  19.     string db 255, 0, 255 dup (?)
  20.     errmsg db 'Недопустимый символ, можно'
  21.     db 'использовать только цифры',cr,lf,'$'
  22. negflag     dw  0
  23.     d    ends
  24.     cod segment
  25.     ;описываем процедуры ввода и вывода целых чисел
  26.     cr = 0dh ;cr присваиваем значение кода символа
  27.     ;возврата каретки (клавиши «Enter»)
  28.     lf = 0ah ;lf присваиваем значение кода символа
  29.     ;перевода строки
  30. IntegerIn proc
  31.     @@start: mov ah,0ah ;функцией 0a вводим строку
  32.     ;символов и размещаем ее в
  33.     ;области string
  34.     lea dx,string
  35.     int 21h
  36.     xor ax,ax ;обнуляем ax, в котором
  37.     ;будем формировать число
  38.     lea si,string+2 ;устанавливаем si на
  39.     ;первый символ введенной
  40.     ;строки
  41.     mov negflag,ax ;обнуляем флаг
  42.     ;отрицательности числа
  43.     ;(предполагаем, что оно
  44.     ;будет неотрицательным)
  45.     cmp byte ptr [si],'-';первый символ это
  46.     ;минус?
  47.     jne @@m2 ;если нет на m2
  48.     not negflag ;отмечаем, что число
  49.     ;отрицательное
  50.     ;(negflag не равен 0)
  51.     inc si ;продвигаем si со
  52.     ;знака числа к первой
  53.     ;цифре
  54.     jmp @@m ;прыгаем на разбор
  55.     ;строки цифр
  56.     @@m2: cmp byte ptr [si],'+';первый символ это
  57.     ;плюс?
  58.     jne @@m ;если нет на m
  59.     inc si ;продвигаем si со
  60.     ;знака числа к первой
  61.     ;цифре
  62.     ;анализируем текущий символ
  63.     @@m: cmp byte ptr [si],cr ;если это cr строка
  64.     ;закончилась, выходим
  65.     ;из цикла разбора
  66.     ;символов
  67.     je @@ex1
  68.     cmp byte ptr [si],'0';если код символа
  69.     ;меньше кода '0'
  70.     ;это не цифра
  71.     jb @@err ;прыгаем на метку err
  72.     cmp byte ptr [si],'9';если код символа
  73.     ;больше кода '9'
  74.     ;это не цифра
  75.     ja @@err ;прыгаем на метку err
  76.     mov bx,10 ;домножаем полученное
  77.     ;число на основание
  78.     ;системы счисления
  79.     mul bx
  80.     sub byte ptr [si],'0';вычитаем код символа
  81.     ;'0' (получаем
  82.     ;очередную цифру)
  83.     add al,[si] ;добавляем цифру к
  84.     ;числу
  85.     adc ah,0
  86.     inc si ;продвигаем si к
  87.     ;следующему символу
  88.     jmp @@m ;организуем цикл
  89.     ;функцией 09 выводим сообщение об ошибке
  90.     @@err: lea dx,errmsg
  91.     mov ah,9
  92.     int 21h
  93.     jmp @@start ;повторяем ввод
  94.     @@ex1: cmp negflag,0 ;число положительное?
  95.     je @@ex ;если да выходим
  96.     neg ax ;меняем знак числа
  97.     @@ex: ret
  98. IntegerIn endp
  99.  
  100. IntegerOut proc
  101.     xor cx,cx ;обнуляем счетчик цифр
  102.     mov bx,10 bx помещаем делитель
  103.     cmp ax,0 ;проверяем знак числа
  104.     jge @@m ;если неотрицательное на m
  105.     neg ax ;иначе меняем знак числа
  106.     push ax ;сохраняем число перед вызовом
  107.     ;функции, использующей ax
  108.     mov ah,2 ;функцией 02 выводим знак '-'
  109.     mov dl,'-'
  110.     int 21h
  111.     pop ax ;восстанавливаем число в ax
  112.     @@m: inc cx ;считаем количество
  113.     ;получающихся цифр
  114.     xor dx,dx ;преобразуем делимое к 32
  115.     ;разрядам
  116.     div bx ;получаем очередную цифру
  117.     push dx ;сохраняем ее в стеке
  118.     or ax,ax ;проверяем есть ли еще цифры
  119.     jnz @@m ;если да на метку m
  120.     ;при выходе из цикла в стеке лежат цифры, в cx их
  121.     ;количество
  122.     @@m1: pop dx ;извлекаем цифру из стека
  123.     add dx,'0' ;преобразуем в код символа
  124.     mov ah,2 ;функцией 02 выводим на экран
  125.     int 21h
  126.     loop @@m1 ;повторяем cx раз
  127.     ret ;возвращаемся из процедуры
  128.  
  129. IntegerOut endp
  130.         ;устанавливаем ds на сегмент данных
  131.  
  132. start:  mov ax,d
  133.     mov ds,ax   ;вводим значение переменныой a
  134.     Mov ah,09 ;выводим строку подсказку для a
  135.     Lea dx,msga
  136.     Int 21h
  137.     Call IntegerIn ;вводим число
  138.     Mov a,ax ;помещаем его в область a
  139.         ;вводим значение переменныой b
  140.     Mov ah,09 ;выводим строку подсказку для b
  141.     Lea dx,msgb
  142.     Int 21h
  143.     Call IntegerIn ;вводим число
  144.     Mov b,ax ;помещаем его в область b
  145.     mov ax, a
  146.     sub ax, b
  147.     Cmp ax,0 ;проверяем первый знаменатель
  148.     Jnz m ;если не 0 на m
  149.     Mov ah,09 ;выводим сообщение об ошибке
  150.     Lea dx,err1
  151.     Int 21h
  152.     Jmp error ;выходим
  153. m:  Mov ax,a ;считаем второй знаменатель
  154.     Add ax,b
  155.     Jnz m1 ; если не 0 на m1
  156.     Mov ah,09 ;выводим сообщение об ошибке
  157.     Lea dx,err2
  158.     Int 21h
  159.     Jmp error ;выходим
  160.         ;рассчитываем значение выражения
  161. m1: Mov ax, a
  162.     imul a ;ax:=a^2
  163.     Imul b
  164.     Imul b
  165.     Imul b ;ax:=a^2*b^3
  166.     mov bx,3
  167.     imul bx  ;ax:=3*a^2*b^3
  168.     add ax, 1 ;ax:=3*a^2*b^3+1
  169.     cwd
  170.     mov bx, a ;bx:=a-b
  171.     sub bx, b
  172.     idiv bx ;ax:=(a^2*b^3+1)/(a-b)
  173.     mov cx,ax ;сохранение значения первой дроби в cx
  174.     Mov ax,a
  175.     sal ax,1
  176.     sal ax,1 ;ax:=a/4
  177.     add ax,b ;ax:=a/4+b
  178.     mov bx,a
  179.     add bx,b
  180.     Idiv bx ;считаем значение второй дроби
  181.     Sub cx,ax ;вычитаем
  182.     mov ax,cx
  183.     call IntegerOut ;выводим результат
  184.         ;завершаем работу программы
  185.     mov ax,4c00h кодом завершения 0 без ошибок
  186.     int 21h
  187. error:    mov ax,4cffh кодом завершения 0ffh (-1) с ошибкой
  188.     int 21h
  189. cod ends
  190.     end start

Объяснение кода листинга программы

В данном коде происходит вычисление выражения по формуле a^2*b^3+1/(a-b). Список действий:

  1. Ввод значений переменных a и b с помощью процедуры IntegerIn.
  2. Проверка значения первого знаменателя (a) на ноль. Если он равен нулю, выводится сообщение об ошибке и происходит переход на метку m.
  3. Вычисление второго знаменателя (b) и проверка его значения на ноль. Если он равен нулю, также выводится сообщение об ошибке и происходит переход на метку m.
  4. Вычисление значения выражения по формуле a^2*b^3+1/(a-b).
  5. Сохранение значения первой дроби (a^2*b^3+1) в переменной cx.
  6. Вычисление значения второй дроби (a/4+b) и вычитание ее из значения первой дроби (cx).
  7. Вывод результата вычисления на экран с помощью процедуры IntegerOut.
  8. Завершение работы программы с кодом завершения 0 (без ошибок) или 0ffh (-1) (с ошибкой), в зависимости от наличия ошибок в процессе выполнения программы.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут