Прекращение ввода чисел по нажатию клавиши - Assembler

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

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

Прошу помощи. Вообщем нужно при нажатии клавиши 'z' прекратить ввод чисел с клавиатуры и перейти к метке после которой выполняются другие действия. Получилось скомпоновать некоторый код, который пока что вводит числа со знаком и преобразует их в противоположные, а после ввода цифры 0 выводит введенные числа с противоположным знаком. Вообще прошу помощи с внедрением в код прерывания которое сможет реагировать на клавишу 'z'.
Листинг программы
  1. ideal
  2. P386N
  3. Model Small
  4. Dataseg
  5. s_sword db 'Enter number:',13,10,'$'
  6. output db 'Output number: ',13,10,'$'
  7. s_error db 'ERROR!',13,10,'$'
  8. s_pak db 'Press any key...$'
  9. endline db 13,10,'$'
  10. buffer db 9
  11. Codeseg
  12. ;-------------------------------------------------------------------------------
  13. ;Процедура ввода слова с консоли в десятичном виде (со знаком)
  14. ; выход: AX - слово случае ошибки AX = 0)
  15. ; CF = 1 - ошибка
  16. input_sdec_word:
  17. push dx ;Сохранение DX
  18. mov al,7 ;Ввод максимум 7 символов (-32768) + конец строки
  19. call input_str ;Вызов процедуры ввода строки
  20. call str_to_sdec_word ;Преобразование строки в слово (со знаком)
  21. pop dx ;Восстановление DX
  22. ret
  23. ;-------------------------------------------------------------------------------
  24. ;Процедура ввода строки c консоли
  25. ; вход: AL - максимальная длина символом CR) (1-254)
  26. ; выход: AL - длина введённой строки (не считая символа CR)
  27. ; DX - адрес строки, заканчивающейся символом CR(0Dh)
  28. input_str:
  29. push cx ;Сохранение СX
  30. mov cx,ax ;Сохранение AX в CX
  31. mov ah,0Ah ;Функция DOS 0Ah - ввод строки в буфер
  32. mov [buffer],al ;Запись максимальной длины в первый байт буфера
  33. push bx
  34. lea bx, [buffer+1]
  35. mov [byte bx],0 ;Обнуление второго байта (фактической длины)
  36. pop bx
  37. mov dx,offset buffer ;DX = aдрес буфера
  38. int 21h ;Обращение к функции DOS
  39. mov al,[buffer+1] ;AL = длина введённой строки
  40. add dx,2 ;DX = адрес строки
  41. mov ah,ch ;Восстановление AH
  42. pop cx ;Восстановление CX
  43. ret
  44. ;-------------------------------------------------------------------------------
  45. ;Процедура преобразования десятичной строки в слово со знаком
  46. ; вход: AL - длина строки
  47. ; DX - адрес строки, заканчивающейся символом CR(0Dh)
  48. ; выход: AX - слово случае ошибки AX = 0)
  49. ; CF = 1 - ошибка
  50. str_to_sdec_word:
  51. push bx ;Сохранение регистров
  52. push dx
  53. test al,al ;Проверка длины строки
  54. jz stsdw_error ;Если равно 0, возвращаем ошибку
  55. mov bx,dx ;BX = адрес строки
  56. mov bl,[bx] ;BL = первый символ строки
  57. cmp bl,'-' ;Сравнение первого символа с '-'
  58. jne stsdw_no_sign ;Если не равно, то преобразуем как число без знака
  59. inc dx ;Инкремент адреса строки
  60. dec al ;Декремент длины строки
  61. stsdw_no_sign:
  62. call str_to_udec_word ;Преобразуем строку в слово без знака
  63. jc stsdw_exit ;Если ошибка, то возвращаем ошибку
  64. cmp bl,'-' ;Снова проверяем знак
  65. jne stsdw_plus ;Если первый символ не '-', то число положительное
  66. cmp ax,32768 ;Модуль отрицательного числа должен быть не больше 32768
  67. ja stsdw_error ;Если больше (без знака), возвращаем ошибку
  68. neg ax ;Инвертируем число
  69. jmp stsdw_ok ;Переход к нормальному завершению процедуры
  70. stsdw_plus:
  71. cmp ax,32767 ;Положительное число должно быть не больше 32767
  72. ja stsdw_error ;Если больше (без знака), возвращаем ошибку
  73. stsdw_ok:
  74. clc ;CF = 0
  75. jmp stsdw_exit ;Переход к выходу из процедуры
  76. stsdw_error:
  77. xor ax,ax ;AX = 0
  78. stc ;CF = 1 (Возвращаем ошибку
  79. stsdw_exit:
  80. pop dx ;Восстановление регистров
  81. pop bx
  82. ret
  83. ;-------------------------------------------------------------------------------
  84. ;Процедура преобразования десятичной строки в слово без знака
  85. ; вход: AL - длина строки
  86. ; DX - адрес строки, заканчивающейся символом CR(0Dh)
  87. ; выход: AX - слово случае ошибки AX = 0)
  88. ; CF = 1 - ошибка
  89. str_to_udec_word:
  90. push cx ;Сохранение всех используемых регистров
  91. push dx
  92. push bx
  93. push si
  94. push di
  95. mov si,dx ;SI = адрес строки
  96. mov di,10 ;DI = множитель 10 (основание системы счисления)
  97. movzx cx,al ;CX = счётчик цикла = длина строки
  98. jcxz studw_error ;Если длина = 0, возвращаем ошибку
  99. xor ax,ax ;AX = 0
  100. xor bx,bx ;BX = 0
  101. studw_lp:
  102. mov bl,[si] ;Загрузка в BL очередного символа строки
  103. inc si ;Инкремент адреса
  104. cmp bl,'0' ;Если код символа меньше кода '0'
  105. jl studw_error ; возвращаем ошибку
  106. cmp bl,'9' ;Если код символа больше кода '9'
  107. jg studw_error ; возвращаем ошибку
  108. sub bl,'0' ;Преобразование символа-цифры в число
  109. mul di ;AX = AX * 10
  110. jc studw_error ;Если результат больше 16 бит - ошибка
  111. add ax,bx ;Прибавляем цифру
  112. jc studw_error ;Если переполнение - ошибка
  113. loop studw_lp ;Команда цикла
  114. jmp studw_exit ;Успешное завершение (здесь всегда CF = 0)
  115. studw_error:
  116. xor ax,ax ;AX = 0
  117. stc ;CF = 1 (Возвращаем ошибку)
  118. studw_exit:
  119. pop di ;Восстановление регистров
  120. pop si
  121. pop bx
  122. pop dx
  123. pop cx
  124. ret
  125. ;----------------------------------------------------------------------
  126. ;Процедура преобразования слова в строку в десятичном виде (без знака)
  127. ; AX - слово
  128. ; DI - буфер для строки (5 символов). Значение регистра не сохраняется.
  129. word_to_udec_str:
  130. push ax
  131. push cx
  132. push dx
  133. push bx
  134. xor cx,cx ;Обнуление CX
  135. mov bx,10 BX делитель (10 для десятичной системы)
  136. wtuds_lp1: ;Цикл получения остатков от деления
  137. xor dx,dx ;Обнуление старшей части двойного слова
  138. div bx ;Деление AX=(DX:AX)/BX, остаток в DX
  139. add dl,'0' ;Преобразование остатка в код символа
  140. push dx ;Сохранение в стеке
  141. inc cx ;Увеличение счетчика символов
  142. test ax,ax ;Проверка AX
  143. jnz wtuds_lp1 ;Переход к началу цикла, если частное не 0.
  144. wtuds_lp2: ;Цикл извлечения символов из стека
  145. pop dx ;Восстановление символа из стека
  146. mov [di],dl ;Сохранение символа в буфере
  147. inc di ;Инкремент адреса буфера
  148. loop wtuds_lp2 ;Команда цикла
  149. pop bx
  150. pop dx
  151. pop cx
  152. pop ax
  153. ret
  154. ;----------------------------------------------------------------------
  155. ;Процедура преобразования слова в строку в десятичном виде (со знаком)
  156. ; AX - слово
  157. ; DI - буфер для строки (6 символов). Значение регистра не сохраняется.
  158. word_to_sdec_str:
  159. push ax
  160. test ax,ax ;Проверка знака AX
  161. jns wtsds_no_sign ;Если >= 0, преобразуем как беззнаковое
  162. mov [byte di],'-' ;Добавление знака в начало строки
  163. inc di ;Инкремент DI
  164. neg ax ;Изменение знака значения AX
  165. wtsds_no_sign:
  166. call word_to_udec_str ;Преобразование беззнакового значения
  167. pop ax
  168. ret
  169. ;----------------------------------------------------------------------
  170. ;Процедура вывода слова на консоль в десятичном виде (со знаком)
  171. ; AX - слово
  172. print_word_sdec:
  173. push di
  174. mov di,offset buffer ;DI = адрес буфера
  175. push di ;Сохранение DI в стеке
  176. call word_to_sdec_str ;Преобразование слова в AX в строку
  177. mov [byte di],'$' ;Добавление символа конца строки
  178. pop di ;DI = адрес начала строки
  179. call print_str ;Вывод строки на консоль
  180. pop di
  181. ret
  182. ;-------------------------------------------------------------------------------
  183. ;Процедура вывода строки на консоль
  184. ; DI - адрес строки
  185. print_str:
  186. push ax
  187. mov ah,9 ;Функция DOS 09h - вывод строки
  188. xchg dx,di ;Обмен значениями DX и DI
  189. int 21h ;Обращение к функции DOS
  190. xchg dx,di ;Обмен значениями DX и DI
  191. pop ax
  192. ret
  193. ;-------------------------------------------------------------------------------
  194. ;Процедура вывода конца строки (CR+LF)
  195. print_endline:
  196. push di
  197. mov di,offset endline ;DI = адрес строки с символами CR,LF
  198. call print_str ;Вывод строки на консоль
  199. pop di
  200. ret
  201. Main:
  202. mov ax, @data
  203. mov ds, ax
  204. mov cx,offset print_str ;Адрес процедуры print_str
  205. mov bx,offset print_endline ;Адрес процедуры print_endline
  206. in_sword_lp:
  207. mov di,offset s_sword
  208. call cx ;Вывод строки 'Enter number:'
  209. xor cx,cx ;Обнуляем регистр CX
  210. input_number:
  211. call input_sdec_word ;Ввод слова со знаком
  212. mov bx,offset print_endline ;Адрес процедуры print_endline
  213. call bx ;Вывод конца строки
  214. cmp ax, 0
  215. je output_text
  216. neg ax
  217. push ax
  218. inc cx
  219. jmp input_number
  220. output_text:
  221. lea di, [output]
  222. lea bx, [print_str]
  223. call bx
  224. output_bumber:
  225. pop ax
  226. call print_word_sdec ;Вывод AX в десятичном виде (со знаком)
  227. lea bx, [print_endline] ;Адрес процедуры print_endline
  228. call bx
  229. loop output_bumber
  230. ;call bx ;Вывод конца строки
  231. ;jnc exit ;Если нет ошибки, переход к выходу из программы
  232. ;mov di,offset s_error
  233. ;call cx ;Вывод строки 'ERROR!'
  234. ;jmp in_sword_lp ;Переход к началу цикла
  235. exit:
  236. lea di, [s_pak]
  237. lea bx, [print_str]
  238. call bx ;Вывод строки 'Press any key...'
  239. mov ah,8 ;Функция DOS 08h - ввод символа без эха
  240. int 21h
  241. mov ax,4C00h ;\
  242. int 21h ;/ Завершение программы
  243. Stack 100
  244. End Main

Решение задачи: «Прекращение ввода чисел по нажатию клавиши»

textual
Листинг программы
  1.  ; строка(38)
  2.  lea bx, [buffer+1]
  3.  
  4.  ; определи этот буфер так (строка 11):
  5.  buffer   db  9,0,9 dup(0)

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


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

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

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

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

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

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