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

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

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

Вычислить заданные условные выражения,исходные данные должны вводится с клавиатуры с проверкой на область допустимые значений. 1ый курс ассемблера, ничего в нем не понимаю, Самостоятельные попытки разобраться привели к полному краху

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

textual
Листинг программы
  1. LOCALS
  2.  
  3. .model small
  4.  
  5. .stack 100h
  6.  
  7. .data
  8.         PromptA db      'Введите число (-32768..+32767): A = ', '$'
  9.         PromptB db      'Введите число (-32768..+32767): B = ', '$'
  10.  
  11.         msgErr  db      'Divide by zero', 0Dh, 0Ah, '$'
  12.         msgFmt  db      'Format error', 0Dh, 0Ah, '$'
  13.         msgShowX db     'X = ', '$'
  14.  
  15.         A       dw      ?
  16.         B       dw      ?
  17.         X       dw      ?
  18.  
  19.         KeyBuf  db      7, 0, 7 dup(0)      ;max,len,string,CR(0dh)
  20.         CR_LF   db      0Dh, 0Ah, '$'
  21.  
  22. .code
  23.  
  24. main    proc
  25.         mov     ax,     @data
  26.         mov     ds,     ax
  27.  
  28.         ;-----------------------------
  29.         ;ввод A
  30.         ;-----------------------------
  31. @@InputA:
  32.         ;вывод приглашения и ввод строки
  33.         mov     ah,     09h
  34.         lea     dx,     PromptA
  35.         int     21h
  36.         mov     ah, 0Ah
  37.         mov     dx, offset KeyBuf
  38.         int     21h
  39.         ;перевод строки (на новую строку)
  40.         lea     dx, CR_LF
  41.         mov     ah,09h
  42.         int     21h
  43.         ; преобразование строки в число
  44.         lea     si, KeyBuf+1
  45.         lea     di, A
  46.         call    Str2Num
  47.         ; проверка на ошибку
  48.         jnc     @@InputB
  49.         ; если есть ошибка ввода - напечатать сообщение об ошибке
  50.         lea     dx, msgFmt
  51.         mov     ah,09h
  52.         int     21h
  53.         jmp     @@InputA
  54.         ;-----------------------------
  55.         ;ввод B
  56.         ;-----------------------------
  57. @@InputB:
  58.         ;вывод приглашения и ввод строки
  59.         mov     ah,     09h
  60.         lea     dx,     PromptB
  61.         int     21h
  62.         mov     ah, 0Ah
  63.         mov     dx, offset KeyBuf
  64.         int     21h
  65.         ;перевод строки (на новую строку)
  66.         lea     dx, CR_LF
  67.         mov     ah,09h
  68.         int     21h
  69.         ; преобразование строки в число
  70.         lea     si, KeyBuf+1
  71.         lea     di, B
  72.         call    Str2Num
  73.         ; проверка на ошибку
  74.         jnc     @@CalcX
  75.         ; если есть ошибка ввода - напечатать сообщение об ошибке
  76.         lea     dx, msgFmt
  77.         mov     ah,09h
  78.         int     21h
  79.         jmp     @@InputB
  80.         ;-----------------------------
  81.         ;вычисление X по формуле
  82.         ;-----------------------------
  83. @@CalcX:
  84.         mov     ax,     A
  85.         cmp     ax,     B
  86.         je      @@Equal
  87.         jg      @@Greater
  88.  
  89.         ;вычисления при a<b
  90. @@Lesser:
  91.         ;проверка ОДЗ
  92.         cmp     B,      0
  93.         jnz     @@Lesser2
  94.         mov     ah,     09h     ;вывод сообщения об ошибке
  95.         lea     dx,     msgErr  ; параметры не в ОДЗ
  96.         int     21h
  97.         jmp     @@InputA        ;повторный ввод параметров
  98. @@Lesser2:
  99.         mov     ax,     A       ;(dx:ax):=A
  100.         cwd
  101.         idiv    B               ;ax:=A/B
  102.         add     ax,     10      ;ax:=(A/B)+10
  103.         mov     X,      ax      ;сохранить результат в X
  104.         jmp     @@Exit
  105.         ;вычисления при a=b
  106. @@Equal:
  107.         mov     ax,     -51
  108.         mov     X,      ax      ;X:=-51
  109.         jmp     @@Exit
  110.         ;вычисления при a>b
  111. @@Greater:
  112.         ;проверка ОДЗ
  113.         cmp     A,      0
  114.         jnz     @@Greater2
  115.         mov     ah,     09h     ;вывод сообщения об ошибке
  116.         lea     dx,     msgErr  ; параметры не в ОДЗ
  117.         int     21h
  118.         jmp     @@InputA        ;повторный ввод параметров
  119. @@Greater2:
  120.         mov     ax,     A       ;(dx:ax):=A*B
  121.         imul    B
  122.         sub     ax,     4       ;(dx:ax):=A*B-4
  123.         sbb     dx,     0
  124.         idiv    A               ;ax:=(A*B-4)/A
  125.         mov     X,      ax
  126.  
  127. @@Exit:
  128.         ;вывод результата
  129.         mov     ah,     09h
  130.         lea     dx,     msgShowX
  131.         int     21h
  132.         mov     ax,     X
  133.         call    Show_AX
  134.         ;завершение программы
  135.         mov     ax,     4C00h
  136.         int     21h
  137. main    endp
  138.  
  139. ; преобразования строки в число
  140. ; на входе:
  141. ; ds:[si] - строка с числом
  142. ; ds:[di] - адрес числа
  143. ; на выходе
  144. ; ds:[di] - число
  145. ; CY - флаг переноса (при ошибке - установлен, иначе - сброшен)
  146. Str2Num proc
  147.         push    ax
  148.         push    bx
  149.         push    cx
  150.         push    dx
  151.         push    ds
  152.         push    es
  153.         push    si
  154.  
  155.         push    ds
  156.         pop     es
  157.  
  158.         mov     cl, ds:[si]
  159.         xor     ch, ch
  160.  
  161.         inc     si
  162.  
  163.         mov     bx, 10
  164.         xor     ax, ax
  165.  
  166.         ;если в строке первый символ '-'
  167.         ; - перейти к следующему
  168.         ; - уменьшить количество рассматриваемых символов
  169.         cmp     byte ptr [si], '-'
  170.         jne     @@Loop
  171.         inc     si
  172.         dec     cx
  173. @@Loop:
  174.         mul     bx         ; умножаем ax на 10 ( dx:ax=ax*bx )
  175.         mov     [di], ax   ; игнорируем старшее слово
  176.         cmp     dx, 0      ; проверяем, результат на переполнение
  177.         jnz     @@Error
  178.  
  179.         mov     al, [si]   ; Преобразуем следующий символ в число
  180.         cmp     al, '0'
  181.         jb      @@Error
  182.         cmp     al, '9'
  183.         ja      @@Error
  184.         sub     al, '0'
  185.         xor     ah, ah
  186.         add     ax, [di]
  187.         jc      @@Error    ; Если сумма больше 65535
  188.         cmp     ax, 8000h
  189.         ja      @@Error
  190.         inc     si
  191.  
  192.         loop    @@Loop
  193.  
  194.         pop     si         ;проверка на знак
  195.         push    si
  196.         inc     si
  197.         cmp     byte ptr [si], '-'
  198.         jne     @@Check    ;если должно быть положительным
  199.         neg     ax         ;если должно быть отрицательным
  200.         jmp     @@StoreRes
  201. @@Check:                   ;дополнительная проверка, когда при вводе положительного числа получили отрицательное
  202.        or       ax, ax     ;
  203.        js       @@Error
  204. @@StoreRes:                ;сохранить результат
  205.         mov     [di], ax
  206.         clc
  207.         pop     si
  208.         pop     es
  209.         pop     ds
  210.         pop     dx
  211.         pop     cx
  212.         pop     bx
  213.         pop     ax
  214.         ret
  215. @@Error:
  216.         xor     ax, ax
  217.         mov     [di], ax
  218.         stc
  219.         pop     si
  220.         pop     es
  221.         pop     ds
  222.         pop     dx
  223.         pop     cx
  224.         pop     bx
  225.         pop     ax
  226.         ret
  227. Str2Num endp
  228.  
  229. ; выводит число из регистра AX на экран
  230. ; входные данные:
  231. ; ax - число для отображения
  232. Show_AX proc
  233.         push    ax
  234.         push    bx
  235.         push    cx
  236.         push    dx
  237.         push    di
  238.  
  239.         mov     cx, 10          ; cx - основание системы счисления
  240.         xor     di, di          ; di - кол. цифр в числе
  241.  
  242.         ; если число в ax отрицательное, то
  243.         ;1) напечатать '-'
  244.         ;2) сделать ax положительным
  245.         or      ax, ax
  246.         jns     @@Conv
  247.         push    ax
  248.         mov     dx, '-'
  249.         mov     ah, 2           ; ah - функция вывода символа на экран
  250.         int     21h
  251.         pop     ax
  252.  
  253.         neg     ax
  254.  
  255. @@Conv:
  256.         xor     dx, dx
  257.         div     cx              ; dl = num mod 10
  258.         add     dl, '0'         ; перевод в символьный формат
  259.         inc     di
  260.         push    dx              ; складываем в стэк
  261.         or      ax, ax
  262.         jnz     @@Conv
  263.         ; выводим из стэка на экран
  264. @@Show:
  265.         pop     dx              ; dl = очередной символ
  266.         mov     ah, 2           ; ah - функция вывода символа на экран
  267.         int     21h
  268.         dec     di              ; повторяем пока di<>0
  269.         jnz     @@Show
  270.  
  271.         pop     di
  272.         pop     dx
  273.         pop     cx
  274.         pop     bx
  275.         pop     ax
  276.         ret
  277. Show_AX endp
  278.  
  279. end     main

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

Этот код на ассемблере вычисляет выражение, введенное пользователем, и выводит результат на экран. Ввод осуществляется с помощью функции Str2Num, которая преобразует строку в число. Код проверяет ошибки ввода, такие как ввод отрицательного числа, и выводит соответствующее сообщение об ошибке. После ввода обоих параметров и их преобразования в числа, код проверяет, является ли A меньше B, и выводит соответствующее сообщение. Если A равно B, выводится сообщение об ошибке. Если A больше B, результат вычисления A*B-4 делится на A и сохраняется в X. Затем выводится сообщение с результатом.

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


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

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

11   голосов , оценка 3.909 из 5

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

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

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