Интересный калькулятор на TASM - Assembler

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

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

Всем доброго времени суток. Такой вопрос: есть калькулятор, который выполняет 4 простейших арифметических операций с двумя числами. Задача заключается в том чтобы его немного модифицировать и упростить согласно тз: написать калькулятор, выполняющий над двумя знаковыми числами размером в слово следующие операции: нахождение максимального, минимального и среднего арифметического значений (все отдельно, можно через процедуры) ну и вывод их на экран соответственно. Заранее спасибо!
Листинг программы
  1. .model tiny ;COM - файл
  2. .code
  3. .386 ;используем eax
  4. org 100h
  5. start:
  6. vvod1: ;выбор функции
  7. xor eax,eax ;обнуляем регистры
  8. xor edx,edx ;
  9. call clrscr
  10. mov ah,9 ;Вывод сторки мессаге1
  11. mov dx,offset message1 ;
  12. int 21h ;
  13. mov ah,08h ;считать символ с клавиатуры
  14. int 21h ;
  15. cmp al,'+' ;сравнение с '+'
  16. je cloj ;значит складываем
  17. cmp al,'-'
  18. je vich ;вычитание
  19. cmp al,'/'
  20. je dele ;деление
  21. cmp al,'*'
  22. je rr1 ;используем jmp т.к далеко
  23. jmp rr ;
  24. rr1: jmp umnoj ;Умножение
  25. rr: cmp al,'q' ;выход
  26. je quit
  27. cmp al,'Q'
  28. je quit
  29. jmp short vvod1 ;если не ввели то повторять ввод
  30. quit:
  31. ret ;Выход
  32. cloj: ;Сложение dx+ax->ax
  33. call clrscr ;стереть экран
  34. call aa1 ;ввод а
  35. push dx ;сохраняем dx в стеке
  36. call bb1 ;ввод b
  37. pop dx ;вытаскиваем dx из стека
  38. add ax,dx ;складываем ax и dx результат в eax
  39. call print
  40. call endstrd
  41. mov ah,9 ;Вывод сторки мессаге2
  42. mov dx,offset message2 ;
  43. int 21h
  44. mov ah,08h
  45. int 21h ;
  46. jmp vvod1
  47. vich: ;вычитание
  48. call clrscr ;стереть экран
  49. call aa1 ;ввод а
  50. push dx
  51. call bb1 ;ввод b
  52. pop dx
  53. sub dx,ax ;вычитаем из dx ax результат в edx
  54. mov ax,dx ;переносим его eax
  55. call print ;выводит eax в десятичной системе
  56. call endstrd
  57. mov ah,9 ;Вывод сторки мессаге2
  58. mov dx,offset message2 ;
  59. int 21h
  60. mov ah,08h
  61. int 21h ;
  62. jmp vvod1
  63. dele: ;деление (цело численное)
  64. call clrscr ;стереть экран
  65. call aa1 ;ввод а
  66. push dx
  67. call bb1 ;ввод b
  68. pop dx
  69. xchg dx,ax
  70. mov cx,dx ;сохраняем делитель в cx
  71. xor dx,dx ;обнуляем dx там будет остаток
  72. div cx ;делим результат в eax
  73. call print
  74. call endstrd
  75. mov ah,9 ;Вывод сторки мессаге2
  76. mov dx,offset message2 ;
  77. int 21h
  78. mov ah,08h
  79. int 21h ;
  80.  
  81. jmp vvod1
  82. umnoj: ;умножение
  83. call clrscr ;стереть экран
  84. call aa1 ;ввод а
  85. push dx
  86. call bb1 ;ввод b
  87. pop dx
  88. mul edx ;умножаем результат в eax
  89. call print
  90. call endstrd
  91. mov ah,9 ;Вывод сторки мессаге2
  92. mov dx,offset message2 ;
  93. int 21h
  94. mov ah,08h
  95. int 21h ;
  96. jmp vvod1
  97. clrscr:
  98. xor dx,dx ;положение курсора dh-строка dl-столбец
  99. mov ah,02h ;установить в 0,0
  100. int 10h ;
  101. mov bl,0000111b ;атрибут символов белый на чёрном
  102. mov cx,25*80 ;количество символов
  103. mov ax,0920h ;вывод 25*80 пробелов
  104. int 10h ;
  105. ret
  106. endp
  107. aa1: ;ввод а
  108. mov dx,offset aaaa
  109. mov ah,9
  110. int 21h
  111. call mover
  112. mov dx,ax ;перенесём в dx
  113. ret
  114. endp
  115. bb1: ;ввод а
  116. mov dx,offset bbbb
  117. mov ah,9
  118. int 21h
  119. call mover
  120. ret
  121. endp
  122. mover:
  123. mov dx,offset bufer ;аресс буфера
  124. mov ah,0ah ;считать строку данных в буфер
  125. int 21h ;
  126. mov dx,offset endstr ;перенос курсора на строку ниже
  127. mov ah,9 ;
  128. int 21h ;
  129. ;перевод из строки в бинарное число
  130. xor di,di ;начало буферв
  131. xor ax,ax ;текущее значение ax
  132. mov cl,blength
  133. xor ch,ch
  134. xor bx,bx
  135. mov si,cx ;длинна буфера
  136. mov cl,10 ;множитель
  137. tohex:
  138. mov bl,byte ptr bconteg[di]
  139. sub bl,'0' ;цифра = код символа - код символа '0'
  140. jb tata ;если ко символа < чем код '0'
  141. cmp bl,9 ;или > чем '9'
  142. ja tata ;начать ввод занаво
  143. mul cx ;иначе умножить на 10
  144. add ax,bx ;добавить к ax новую цифру
  145. inc di ;увеличить адресс
  146. cmp di,si ;если он меньше чем кол. символов + 1
  147. jb tohex
  148. jmp tra
  149. tata: jmp vvod1 ;Нужно использовать дальний переход
  150. tra: ret
  151. endp
  152. print:
  153. mov ebx,0ah ;делитель
  154. xor cx,cx ;счётчик
  155. divloop:
  156. xor edx,edx ;обнуляем edx
  157. div ebx ;делим на 10
  158. add edx,'0' ;дописываем к остатку деления код нуля
  159. push edx ;сохраняем число в стеке
  160. inc cx ;увеличиваем счётчик на 1
  161. test eax,eax ;если есть что делить то
  162. jnz divloop ;продолжаем делить(если не ноль)
  163. restore:
  164. pop eax ;читаем записанные числа из стека
  165. mov edx,eax ;пишем их в eax
  166. mov ah,2 ;функция вывода символа по коду код в al
  167. int 21h ;
  168. dec cx ;уменьшаем счетчик
  169. cmp cx,0 ;если он не = нолю
  170. jne restore ;то проолжаем вывод
  171. ret
  172. endp
  173. endstrd:
  174. mov dx,offset endstr ;перенос курсора на строку ниже
  175. mov ah,9 ;
  176. int 21h ;
  177. ret
  178. endp
  179. ret
  180. message1 db "PRESS",0dh,0ah
  181. db "+ for add. a+b.",0dh,0ah
  182. db "- for sub. a-b",0dh,0ah
  183. db "/ for div. a/b",0dh,0ah
  184. db "* for mul. a*b",0dh,0ah
  185. db "q for quit",0dh,0ah,'$'
  186. message2 db "Press any key",0dh,0ah,'$'
  187. aaaa db "a=",'$'
  188. bbbb db "b=",'$'
  189. endstr db 0dh,0ah,'$'
  190. enderes db ' ',0dh,0ah,'$'
  191. bufer db 5 ;max размер ввода чисел
  192. blength db ? ;размер буфера после считывания
  193. bconteg: ;содержимое буфера будет за концом файла
  194. hexstring equ bconteg
  195. end start

Решение задачи: «Интересный калькулятор на TASM»

textual
Листинг программы
  1.     LOCALS              ;разрешение одинаковых локальных меток (начинающихся с @@)
  2.     .model tiny         ;COM - файл
  3.     .code
  4.     .386                ;используем eax
  5.     org 100h
  6. start:
  7. vvod1:                  ;выбор функции
  8.     call clrscr
  9.     mov ah,9            ;Вывод сторки мессаге1
  10.     mov dx,offset message1      ;
  11.     int 21h             ;
  12.     mov ah,08h          ;считать символ с клавиатуры
  13.     int 21h             ;
  14.     Case1:
  15.         cmp al,'m'      ;сравнение с '+'
  16.         jne Case2
  17.         call EnterAB
  18.         call Min        ;значит возвращаем минимум
  19.         call ShowResult
  20.         jmp vvod1
  21.     Case2:
  22.         cmp al,'M'
  23.         jne Case3
  24.         call EnterAB
  25.         call Max        ;значит возвращаем максимум
  26.         call ShowResult
  27.         jmp vvod1
  28.     Case3:
  29.         cmp al,'a'
  30.         jne Case4
  31.         call EnterAB
  32.         call Average    ;значит возвращаем среднее арифметическое
  33.         call ShowResult
  34.         jmp vvod1
  35.     Case4:
  36.         cmp al,'q'      ;выход
  37.         je quit
  38.         cmp al,'Q'
  39.         je quit
  40.     jmp short vvod1         ;если не ввели то повторять ввод
  41. quit:
  42.     int 20h             ;Выход
  43. ;Минимальное число
  44. ;на входе:
  45. ; ax - первое число
  46. ; bx - второе число
  47. ;на выходе:
  48. ; ax - минимальное из двух чисел
  49. Min     proc
  50.     cmp ax,bx
  51.     jle @@Skip
  52.     mov ax,bx
  53. @@Skip:
  54.         ret
  55. Min     endp
  56.  
  57. ;Максимальное число
  58. ;на входе:
  59. ; ax - первое число
  60. ; bx - второе число
  61. ;на выходе:
  62. ; ax - максимальное из двух чисел
  63. Max     proc
  64.     cmp ax,bx
  65.     jge @@Skip
  66.     mov ax,bx
  67. @@Skip:
  68.         ret
  69. Max     endp
  70.  
  71. ;Максимальное число
  72. ;на входе:
  73. ; ax - первое число
  74. ; bx - второе число
  75. ;на выходе:
  76. ; ax - максимальное из двух чисел
  77. Average proc
  78.     add ax,bx           ;складываем ax и bx результат в ax
  79.     sar ax,1            ;делим на 2 при помощи арифметического сдвига
  80.     ret
  81. Average endp
  82.  
  83. ;ввод двух чисел для дальнейших вычислений
  84. ;на входе:
  85. ; -
  86. ;на выходе:
  87. ;ax - число A
  88. ;bx - число B
  89. EnterAB proc
  90.     call clrscr
  91. @@ReadA:
  92.     mov dx,offset aaaa
  93.     mov ah,9
  94.     int 21h
  95.     mov ah, 0Ah
  96.     lea dx, bufer
  97.     int 21h
  98.     lea si, bufer+1
  99.     call Str2Num
  100.     jc @@ReadA
  101.     push ax
  102.     call newstr
  103. @@ReadB:
  104.     mov dx,offset bbbb
  105.     mov ah,9
  106.     int 21h
  107.     mov ah, 0Ah
  108.     lea dx, bufer
  109.     int 21h
  110.     lea si, bufer+1
  111.     call Str2Num
  112.     jc @@ReadB
  113.     push ax
  114.     call newstr
  115.     pop bx
  116.     pop ax
  117.     ret
  118. EnterAB endp
  119.  
  120. ;вывод строки результата и ожидание нажатия клавиши
  121. ;на входе
  122. ;ax - знаковое число для вывода в качестве результата
  123. ShowResult      proc
  124.         call Show_AX
  125.         call NewStr
  126.         mov ah,9
  127.         mov dx,offset message2      ;
  128.         int 21h
  129.         mov ah,08h
  130.         int 21h
  131.         mov ah, 06h     ;считываем второй символ при нажатии функциональной клавиши
  132.         mov dl, 0FFh
  133.         int 21h
  134.         ret
  135. ShowResult      endp
  136.  
  137. ; преобразования строки в число
  138. ; на входе:
  139. ; ds:[si] - строка с числом
  140. ; на выходе
  141. ; ax - число
  142. ; CY - флаг переноса (при ошибке - установлен, иначе - сброшен)
  143. Str2Num PROC
  144. LOCAL R: word
  145.         pusha
  146.         push    ds
  147.         push    es
  148.  
  149.         push    ds
  150.         pop     es
  151.  
  152.         mov     cl, ds:[si]
  153.         xor     ch, ch
  154.         jcxz    @@Error
  155.         push    si      ;для дальнейшей проверки знака
  156.         inc     si
  157.  
  158.         mov     bx, 10
  159.         xor     ax, ax
  160.  
  161.         ;если в строке первый символ '-'
  162.         ; - перейти к следующему
  163.         ; - уменьшить количество рассматриваемых символов
  164.         cmp     byte ptr [si], '-'
  165.         jne     @@Loop
  166.         inc     si
  167.         dec     cx
  168. @@Loop:
  169.         mul     bx         ; умножаем ax на 10 ( dx:ax=ax*bx )
  170.         mov     [di], ax   ; игнорируем старшее слово
  171.         cmp     dx, 0      ; проверяем, результат на переполнение
  172.         jnz     @@ErrorWithPopSI
  173.  
  174.         mov     al, [si]   ; Преобразуем следующий символ в число
  175.         cmp     al, '0'
  176.         jb      @@ErrorWithPopSI
  177.         cmp     al, '9'
  178.         ja      @@ErrorWithPopSI
  179.         sub     al, '0'
  180.         xor     ah, ah
  181.         add     ax, [di]
  182.         jc      @@ErrorWithPopSI    ; Если сумма больше 65535
  183.         cmp     ax, 8000h
  184.         ja      @@ErrorWithPopSI
  185.         inc     si
  186.  
  187.         loop    @@Loop
  188.  
  189.         pop     si         ;проверка на знак
  190.         inc     si
  191.         cmp     byte ptr [si], '-'
  192.         jne     @@Check    ;если должно быть положительным
  193.         neg     ax         ;если должно быть отрицательным
  194.         jmp     @@StoreRes
  195. @@Check:                   ;дополнительная проверка, когда при вводе положительного числа получили отрицательное
  196.         or       ax, ax    ;
  197.         js       @@Error
  198. @@StoreRes:                ;сохранить результат
  199.         mov     R, ax
  200.         clc
  201.         pop     es
  202.         pop     ds
  203.         popa
  204.         mov     ax, R
  205.         ret
  206. @@ErrorWithPopSI:
  207.         pop     si
  208. @@Error:
  209.         xor     ax, ax
  210.         mov     R, ax
  211.         stc
  212.         pop     es
  213.         pop     ds
  214.         popa
  215.         mov     ax, R
  216.         ret
  217. Str2Num ENDP
  218.  
  219. ; выводит число из регистра AX на экран
  220. ; входные данные:
  221. ; ax - число для отображения
  222. Show_AX proc
  223.         push    ax
  224.         push    bx
  225.         push    cx
  226.         push    dx
  227.         push    di
  228.  
  229.         mov     cx, 10          ; cx - основание системы счисления
  230.         xor     di, di          ; di - кол. цифр в числе
  231.  
  232.         ; если число в ax отрицательное, то
  233.         ;1) напечатать '-'
  234.         ;2) сделать ax положительным
  235.         or      ax, ax
  236.         jns     @@Conv
  237.         push    ax
  238.         mov     dx, '-'
  239.         mov     ah, 2           ; ah - функция вывода символа на экран
  240.         int     21h
  241.         pop     ax
  242.  
  243.         neg     ax
  244.  
  245. @@Conv:
  246.         xor     dx, dx
  247.         div     cx              ; dl = num mod 10
  248.         add     dl, '0'         ; перевод в символьный формат
  249.         inc     di
  250.         push    dx              ; складываем в стэк
  251.         or      ax, ax
  252.         jnz     @@Conv
  253.         ; выводим из стека на экран
  254. @@Show:
  255.         pop     dx              ; dl = очередной символ
  256.         mov     ah, 2           ; ah - функция вывода символа на экран
  257.         int     21h
  258.         dec     di              ; повторяем пока di<>0
  259.         jnz     @@Show
  260.  
  261.         pop     di
  262.         pop     dx
  263.         pop     cx
  264.         pop     bx
  265.         pop     ax
  266.         ret
  267. Show_AX endp
  268.  
  269. clrscr  proc
  270.         pusha
  271.         mov     ax,     0700h   ;функция SCROLL DOWN
  272.         ;mov    al,     10      ;число пустых строк, вдвигаемых сверху (0=очистить все окно)
  273.         mov     bh,     07h     ;атрибут для заполнения
  274.         mov     cx,     0000h   ;верхний левый угол окна (считая от 0)
  275.         mov     dx,     24*256+79 ;нижний правый угол окна (считая от 0)
  276.         int     10h
  277.         mov     ah,     0Fh     ;читать текущий видеорежим
  278.         int     10h
  279.         mov     ah,     02h     ;установить курсор в левый верхний угол
  280.         mov     dx,     0000h   ;левый верхний угол
  281.         int     10h
  282.         popa
  283.         ret
  284. clrscr  endp
  285.  
  286. newstr  proc
  287.         pusha
  288.         mov     ah, 09h
  289.         lea     dx, endstr
  290.         int     21h
  291.         popa
  292.         ret
  293. newstr  endp
  294. ;------------------------------------------------------------
  295. message1        db "PRESS",0dh,0ah
  296.                 db "m for min(a,b).",0dh,0ah
  297.                 db "M for max(a,b)",0dh,0ah
  298.                 db "a for (a+b)/2",0dh,0ah
  299.                 db "q for quit",0dh,0ah,'$'
  300. message2        db "Press any key",0dh,0ah,'$'
  301. aaaa            db "a=",'$'
  302. bbbb            db "b=",'$'
  303. endstr          db 0dh,0ah,'$'
  304. enderes         db ' ',0dh,0ah,'$'
  305. bufer           db 5               ;max размер ввода чисел
  306. blength         db ?               ;размер буфера после считывания
  307. bconteg:                ;содержимое буфера будет за концом файла
  308.  
  309. end start

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


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

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

12   голосов , оценка 4.25 из 5

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

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

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