Найти значение выражения. Не получается вывести результат на экран - Assembler

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

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

Добрый вечер! Помогите найти ошибку. Ассемблер изучаю всего несколько дней. Необходимо вычислить значение выражения (A*X+B)div(C*X*X+D*X+E). Ввод данных получилось сделать по образцу при помощи процедур ASCII, а как делать вывод на экран пока не понимаю, возможно ошибка где-то в вычислениях. Компилятор TASM 4.1 через DOSBox 0.74. Заранее спасибо!
Листинг программы
  1. .model tiny ; модель (64 Кб) памяти, используемая для СОМ
  2. .code ; начало сегмента кода
  3. org 100h ; начальное значение счетчика инструкций (IP) - 100h
  4. start: ; метка начала программы, расположена по адресу 100h
  5.  
  6. mov a,ax ; сохранение результата
  7. mov ah,9 ; номер функции вывода на экран - в АН
  8. mov dx,offset message1 ; адрес начала строки - в DX
  9. int 21h ; вызов системной функции DOS
  10. mov ah,0ah ; номер функции ввода с клавиатуры - в АН
  11. lea dx,buf ; адрес начала буфера ввода - в DX
  12. int 21h ; вызов системной функции DOS
  13. call ASCII ; вызов процедуры
  14. mov a,ax ; сохранение результата
  15. mov b,ax ; сохранение результата
  16. mov ah,9 ; номер функции вывода на экран - в АН
  17. mov dx,offset message2 ; адрес начала строки - в DX
  18. int 21h ; вызов системной функции DOS
  19. mov ah,0ah ; номер функции ввода с клавиатуры - в АН
  20. lea dx,buf ; адрес начала буфера ввода - в DX
  21. int 21h ; вызов системной функции DOS
  22. call ASCII ; вызов процедуры
  23. mov b,ax ; сохранение результата
  24. mov c,ax ; сохранение результата
  25. mov ah,9 ; номер функции вывода на экран - в АН
  26. mov dx,offset message3 ; адрес начала строки - в DX
  27. int 21h ; вызов системной функции DOS
  28. mov ah,0ah ; номер функции ввода с клавиатуры - в АН
  29. lea dx,buf ; адрес начала буфера ввода - в DX
  30. int 21h ; вызов системной функции DOS
  31. call ASCII ; вызов процедуры
  32. mov c,ax ; сохранение результата
  33. mov d,ax ; сохранение результата
  34. mov ah,9 ; номер функции вывода на экран - в АН
  35. mov dx,offset message4 ; адрес начала строки - в DX
  36. int 21h ; вызов системной функции DOS
  37. mov ah,0ah ; номер функции ввода с клавиатуры - в АН
  38. lea dx,buf ; адрес начала буфера ввода - в DX
  39. int 21h ; вызов системной функции DOS
  40. call ASCII ; вызов процедуры
  41. mov d,ax ; сохранение результата
  42. mov e,ax ; сохранение результата
  43. mov ah,9 ; номер функции вывода на экран - в АН
  44. mov dx,offset message5 ; адрес начала строки - в DX
  45. int 21h ; вызов системной функции DOS
  46. mov ah,0ah ; номер функции ввода с клавиатуры - в АН
  47. lea dx,buf ; адрес начала буфера ввода - в DX
  48. int 21h ; вызов системной функции DOS
  49. call ASCII ; вызов процедуры
  50. mov e,ax ; сохранение результата
  51. mov x,ax ; сохранение результата
  52. mov ah,9 ; номер функции вывода на экран - в АН
  53. mov dx,offset message6 ; адрес начала строки - в DX
  54. int 21h ; вызов системной функции DOS
  55. mov ah,0ah ; номер функции ввода с клавиатуры - в АН
  56. lea dx,buf ; адрес начала буфера ввода - в DX
  57. int 21h ; вызов системной функции DOS
  58. call ASCII ; вызов процедуры
  59. mov x,ax ; сохранение результата
  60.  
  61. ;-------------
  62. ;вычисление значеня выражения
  63. mov ax,a
  64. mul x ; A*X
  65. mov f,ax
  66. mov ax,f
  67. add ax,b
  68. mov g,ax ;вычислили g
  69. mov ax,x
  70. mul x
  71. mov h,ax
  72. mov ax,c
  73. mul h
  74. mov i,ax
  75. mov ax,d
  76. mul x
  77. mov j,ax
  78. mov ax,i
  79. add ax,j
  80. mov k,ax ;вычислили k
  81. mov ax,k
  82. add ax,e
  83. mov l,ax ;вычислили l
  84. ;-----------------------------
  85. ;вывести результат на экран
  86. mov dx,offset message7
  87. mov ah,9
  88. int 21h
  89. mov dx,ax
  90. int 21h
  91. mov ax,4ch
  92. int 21h
  93. ;-------------
  94.  
  95. ret ; завершение программы
  96. ASCII: ; метка процедуры
  97. xor di,di ; DI = 0 - номер байта в буфере
  98. xor ax,ax ; АХ = 0 - текущее значение результата
  99. mov cl,blength
  100. xor ch,ch
  101. xor bx,bx
  102. mov si,cx ; SI - длина буфера
  103. mov cl,10 ; CL = 10, множитель для MUL
  104. asc2hex:
  105. mov bl,byte ptr bcontent[di] ; считываем очередной символ
  106. sub bl,'0' ; цифра = код цифры - код символа "0",
  107. jb asc_error ; если код символа был меньше, чем код "0",
  108. cmp bl,9 ; или больше, чем "9",
  109. ja asc_error ; выйти из программы с сообщением об ошибке,
  110. mul cx ; иначе: умножить текущий результат на 10,
  111. add ax,bx ; добавить к нему новую цифру,
  112. inc di ; увеличить счетчик
  113. cmp di,si ; если счетчик+1 меньше числа символов -
  114. jb asc2hex ; продолжить (счетчик считается от 0)
  115. ret ; завершение процедуры
  116. asc_error:
  117. mov dx,offset err_msg
  118. mov ah,9
  119. int 21h ; вывести сообщение об ошибке
  120. mov ax,4c00h ; 4c - функция завершения программы (00=return 0)
  121. ;mov ah,4ch можно записать одной командой, а можно двумя
  122. ;mov al,00h
  123. int 21h ; и завершить программу
  124.  
  125. .data
  126. message1 db 0Dh,0Ah, "Enter A : ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  127. message2 db 0Dh,0Ah, "Enter B : ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  128. message3 db 0Ah,0Dh, "Enter C : ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  129. message4 db 0Dh,0Ah, "Enter D : ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  130. message5 db 0Dh,0Ah, "Enter E : ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  131. message6 db 0Ah,0Dh, "Enter X : ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  132. err_msg db 0Dh,0Ah, "Error! ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  133. message7 db 0Dh,0Ah, "Result: ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  134. ;-------------
  135. ;-------------
  136.  
  137. ; Буфер ввода
  138. buf db 10 ; максимальное кол-во символов
  139. blength db ? ; для сохранения длины введённой строки
  140. bcontent db 10 dup (32) ; для хранения введённой строки
  141. a dw 0
  142. b dw 0
  143. c dw 0
  144. d dw 0
  145. e dw 0
  146. x dw 0
  147. f dw 0 ;для умножения
  148. g dw 0
  149. h dw 0
  150. i dw 0
  151. j dw 0
  152. k dw 0
  153. l dw 0
  154. m dw 0 ;для умножения
  155.  
  156. end start ; конец программы

Решение задачи: «Найти значение выражения. Не получается вывести результат на экран»

textual
Листинг программы
  1. .model tiny     ; модель (64 Кб) памяти, используемая для СОМ
  2. .code           ; начало сегмента кода
  3. org 100h        ; начальное значение счетчика инструкций (IP) - 100h
  4.  
  5. start:      ; метка начала программы, расположена по адресу 100h
  6.  
  7.  
  8.         mov     dx,     offset message1 ; адрес начала строки - в DX
  9.         call    InputInt
  10.         mov     a,      ax      ; сохранение результата
  11.  
  12.         mov     dx,     offset message2 ; адрес начала строки - в DX
  13.         call    InputInt
  14.         mov     b,      ax        ; сохранение результата
  15.  
  16.         mov     dx,     offset message3 ; адрес начала строки - в DX
  17.         call    InputInt
  18.         mov     c,      ax        ; сохранение результата
  19.  
  20.         mov     dx,     offset message4 ; адрес начала строки - в DX
  21.         call    InputInt
  22.         mov     d,      ax        ; сохранение результата
  23.  
  24.         mov     dx,     offset message5 ; адрес начала строки - в DX
  25.         call    InputInt
  26.         mov     e,      ax        ; сохранение результата
  27.  
  28.         mov     dx,     offset message6  ; адрес начала строки - в DX
  29.         call    InputInt
  30.         mov     x,      ax        ; сохранение результата
  31.  
  32.  
  33. ;-------------
  34. ;вычисление значеня выражения
  35.  
  36. mov ax,a
  37. mul x       ; A*X
  38. mov f,ax
  39.  
  40. mov ax,f
  41. add ax,b
  42. mov g,ax    ;вычислили g
  43.  
  44. mov ax,x
  45. mul x
  46. mov h,ax
  47.  
  48. mov ax,c
  49. mul h
  50. mov i,ax
  51.  
  52. mov ax,d
  53. mul x
  54. mov j,ax
  55.  
  56. mov ax,i
  57. add ax,j
  58. mov k,ax    ;вычислили k
  59.  
  60. mov ax,k
  61. add ax,e
  62. mov l,ax    ;вычислили l
  63.  
  64. mov ax,g
  65. mov dx, 0
  66. div l
  67. mov m,ax
  68.  
  69. ;-----------------------------
  70. ;вывести результат на экран
  71.         mov     ah,     09h
  72.         mov     dx,     offset message7
  73.         int     21h
  74.  
  75.         mov     ax,     m
  76.         call    OutInt
  77.  
  78.         ;завершение программы
  79.         int     20h
  80.  
  81.  
  82. ; преобразования строки в число
  83. ; на входе:
  84. ; ds:[si] - строка с числом
  85. ; ds:[di] - адрес числа
  86. ; на выходе
  87. ; ds:[di] - число
  88. ; CY - флаг переноса (при ошибке - установлен, иначе - сброшен)
  89. Str2Num PROC
  90.         push    bx
  91.         push    cx
  92.         push    dx
  93.         push    ds
  94.         push    es
  95.         push    si
  96.  
  97.         push    ds
  98.         pop     es
  99.  
  100.         mov     cl, ds:[si]
  101.         xor     ch, ch
  102.  
  103.         inc     si
  104.  
  105.         mov     bx, 10
  106.         xor     ax, ax
  107.  
  108.         ;если в строке первый символ '-'
  109.         ; - перейти к следующему
  110.         ; - уменьшить количество рассматриваемых символов
  111.         cmp     byte ptr [si], '-'
  112.         jne     @@Loop
  113.         inc     si
  114.         dec     cx
  115. @@Loop:
  116.         mul     bx         ; умножаем ax на 10 ( dx:ax=ax*bx )
  117.         mov     [di], ax   ; игнорируем старшее слово
  118.         cmp     dx, 0      ; проверяем, результат на переполнение
  119.         jnz     @@Error
  120.  
  121.         mov     al, [si]   ; Преобразуем следующий символ в число
  122.         cmp     al, '0'
  123.         jb      @@Error
  124.         cmp     al, '9'
  125.         ja      @@Error
  126.         sub     al, '0'
  127.         xor     ah, ah
  128.         add     ax, [di]
  129.         jc      @@Error    ; Если сумма больше 65535
  130.         cmp     ax, 8000h
  131.         ja      @@Error
  132.         inc     si
  133.  
  134.         loop    @@Loop
  135.  
  136.         pop     si         ;проверка на знак
  137.         push    si
  138.         inc     si
  139.         cmp     byte ptr [si], '-'
  140.         jne     @@Check    ;если должно быть положительным
  141.         neg     ax         ;если должно быть отрицательным
  142.         jmp     @@StoreRes
  143. @@Check:                   ;дополнительная проверка, когда при вводе положительного числа получили отрицательное
  144.        or       ax, ax     ;
  145.        js       @@Error
  146. @@StoreRes:                ;сохранить результат
  147.         mov     [di], ax
  148.         clc
  149.         pop     si
  150.         pop     es
  151.         pop     ds
  152.         pop     dx
  153.         pop     cx
  154.         pop     bx
  155.         ret
  156. @@Error:
  157.         xor     ax, ax
  158.         stc
  159.         pop     si
  160.         pop     es
  161.         pop     ds
  162.         pop     dx
  163.         pop     cx
  164.         pop     bx
  165.         ret
  166. Str2Num ENDP
  167.  
  168. ;ввод числа
  169. ;вход
  170. ; ds:dx - строка приглашение
  171. ;выход
  172. ; ax - введённое число
  173. InputInt        proc
  174.         push    si
  175. @@Another:
  176.         push    dx
  177.         mov     ah,     09h     ; номер функции вывода на экран - в АН
  178.         ;mov    dx,offset message1 ; адрес начала строки - в DX
  179.         int     21h             ; вызов системной функции DOS
  180.         mov     ah,     0ah     ; номер функции ввода с клавиатуры - в АН
  181.         lea     dx,     buf     ; адрес начала буфера ввода - в DX
  182.         int     21h             ; вызов системной функции DOS
  183.         pop     dx
  184.  
  185.         lea     si,     buf+1
  186.         call    Str2Num         ; вызов процедуры
  187.         jc      @@Another
  188.         pop     si
  189.         ret
  190. InputInt        endp
  191.  
  192. OutInt proc
  193. ;; если число знаковое, то необходимо расскоментировать следующие строки
  194. ;; Проверяем число на знак.
  195.    test    ax, ax
  196.    jns     oi1
  197. ;
  198. ;; Если оно отрицательное, выведем минус и оставим его модуль.
  199.    mov  cx, ax
  200.    mov     ah, 02h
  201.    mov     dl, '-'
  202.    int     21h
  203.    mov  ax, cx
  204.    neg     ax
  205. ;; Количество цифр будем держать в CX.
  206. oi1:
  207.     xor     cx, cx
  208.     mov     bx, 10 ; основание сс. 10 для десятеричной и т.п.
  209. oi2:
  210.     xor     dx,dx
  211.     div     bx
  212. ; Делим число на основание сс. В остатке получается последняя цифра.
  213. ; Сразу выводить её нельзя, поэтому сохраним её в стэке.
  214.     push    dx
  215.     inc     cx
  216. ; А с частным повторяем то же самое, отделяя от него очередную
  217. ; цифру справа, пока не останется ноль, что значит, что дальше
  218. ; слева только нули.
  219.     test    ax, ax
  220.     jnz     oi2
  221. ; Теперь приступим к выводу.
  222.     mov     ah, 02h
  223. oi3:
  224.     pop     dx
  225. ; Извлекаем очередную цифру, переводим её в символ и выводим.
  226. ;; раскоментировать если основание сс > 10, т.е. для вывода требуются буквы
  227. ;   cmp     dl,9
  228. ;   jbe     oi4
  229. ;   add     dl,7
  230. ;oi4:
  231.     add     dl, '0'
  232.     int     21h
  233. ; Повторим ровно столько раз, сколько цифр насчитали.
  234.     loop    oi3
  235.  
  236.     ret
  237. OutInt endp
  238.  
  239. .data
  240. message1        db 0Dh,0Ah, "Enter A : ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  241. message2        db 0Dh,0Ah, "Enter B : ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  242. message3        db 0Ah,0Dh, "Enter C : ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  243. message4        db 0Dh,0Ah, "Enter D : ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  244. message5        db 0Dh,0Ah, "Enter E : ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  245. message6        db 0Ah,0Dh, "Enter X : ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  246. err_msg         db 0Dh,0Ah, "Error! ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  247. message7        db 0Dh,0Ah, "Result: ",0Dh,0Ah, '$' ; строка для вывода, символ $ - символ конца вывода
  248. ;-------------
  249.  
  250. ;-------------
  251.  
  252. ; Буфер ввода
  253. buf             db 10           ; максимальное кол-во символов
  254. blength         db ?            ; для сохранения длины введённой строки
  255. bcontent        db 10 dup (0)   ; для хранения введённой строки
  256.  
  257. a               dw 0
  258. b               dw 0
  259. c               dw 0
  260. d               dw 0
  261. e               dw 0
  262. x               dw 0
  263.  
  264. f               dw 0            ;для умножения
  265. g               dw 0
  266. h               dw 0
  267. i               dw 0
  268. j               dw 0
  269. k               dw 0
  270. l               dw 0
  271. m               dw 0            ;для умножения
  272.  
  273.  
  274. end             start           ; конец программы

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


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

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

10   голосов , оценка 3.9 из 5

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

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

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