Guest User

Untitled

a guest
May 25th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.75 KB | None | 0 0
  1. ;------------------------------------------------
  2. ; ЛАБОРАТОРНАЯ РАБОТА ПО СП №5
  3. ; "Ввод и вывод в машинном формате"
  4. ;================================================
  5. ; Разработал: Михаил Кучеренко, ИУ5-44, 2018 г.
  6. ;------------------------------------------------
  7. ; Компилить: run.bat SP_Lab5 COM
  8. ;------------------------------------------------
  9. CODE_SEG SEGMENT PARA PUBLIC 'CODE'
  10. ASSUME DS:CODE_SEG, CS:CODE_SEG, SS:CODE_SEG
  11. ORG 100h
  12. ;------------------------------------------------
  13. START:
  14. JMP BODY
  15. ;------------------------------------------------
  16. ; ДАННЫЕ
  17. ;------------------------------------------------
  18. ; Максимальное количество символов в строке
  19. COUNT DW 20
  20. ; Буфер для вывода
  21. BUFFER DB 60 dup('$'), "$"
  22. ; Длина буферной строки
  23. BUFLEN EQU $-BUFFER
  24. ; Символ, завершающий ввод (сейчас - enter)
  25. ENDCHAR DB 0Dh
  26.  
  27. ; Таблица перекодировки
  28. TBL DB "0123456789ABCDEF"
  29. ; Массив для перекодировки HEX
  30. STRING DB 4 dup('$'), "$"
  31.  
  32. ; Массив для перекодировки PRINT_CONVERTED
  33. DECSTR DB 8 dup('X'), "$"
  34.  
  35. ; Кусочки строки для красивого вывода
  36. BEF_LEN DB " (В $"
  37. MID_LEN DB " с/с: $"
  38. AFT_LEN DB ") = $"
  39.  
  40. ; Основание системы счисления для вывода
  41. NUM_SYS DB ?
  42.  
  43. ; Программные уведомления
  44. ERRMSG DB " [ERROR] Неверное основание системы счисления!$"
  45. NUMMSG DB "Введите систему счисления для вывода длины строки: $"
  46. CPROMPT DB "Введите строку для конвертации или '*', чтобы выйти: $"
  47. ENDMSG DB "Завершение программы ...",0Dh,0Ah,"$"
  48. OUTMSG DB "Автор: Михаил Кучеренко, ИУ5-44$"
  49.  
  50. ; Флаг начала процедуры завершения работы
  51. ENDFLAG DB 0
  52. ;------------------------------------------------
  53. ; ПРОЦЕДУРЫ
  54. ;------------------------------------------------
  55. ; Очистка экрана
  56. CLRSCR PROC
  57.  
  58. PUSH AX
  59. MOV AX, 03h
  60. INT 10h
  61. POP AX
  62.  
  63. RET
  64.  
  65. CLRSCR ENDP
  66. ;------------------------------------------------
  67. ; Вывод перевода сроки
  68. CRLF PROC
  69.  
  70. PUSH 0Dh ; Выводим CR
  71. CALL PUTCH
  72.  
  73. PUSH 0Ah ; Выводим LF
  74. CALL PUTCH
  75.  
  76. RET
  77.  
  78. CRLF ENDP
  79. ;------------------------------------------------
  80. ; Ввод одного символа с клавиатуры
  81. GETCH PROC ; Неявно использует AX
  82.  
  83. PUSH DX
  84.  
  85. ; Ожидание ввода символа
  86. MOV AH, 08h
  87. INT 21h
  88.  
  89. ; Игнорируем символы конца строки и enter
  90. CMP AL, '$'
  91. JE GetchEnd
  92. CMP AL, 0Dh
  93. JE GetchEnd
  94.  
  95. ; Выводим остальное
  96. MOV AH, 02h
  97. MOV DL, AL
  98. INT 21h
  99.  
  100. ; Если backspace - заменяем предыдущий символ
  101. CMP AL, 08h
  102. JNE GetchEnd
  103. MOV AH, 02h
  104. MOV DL, ' '
  105. INT 21h
  106. MOV DL, 08h
  107. INT 21h
  108.  
  109. GetchEnd:
  110. POP DX
  111.  
  112. RET
  113.  
  114. GETCH ENDP
  115. ;------------------------------------------------
  116. ; Вывод одного символа, переданного в стек
  117. PUTCH PROC
  118.  
  119. PUSH BP
  120. PUSH DX
  121. PUSH AX
  122.  
  123. ; Получаем положение вершины стека
  124. MOV BP, SP
  125.  
  126. ; Выводим символ из стека
  127. MOV AH, 02h
  128. MOV DL, [bp+8]
  129. ;MOV DL, 48h
  130. INT 21h
  131.  
  132. ; Пишем адрес возврата вместо символа
  133. MOV AX, [bp+6]
  134. MOV [bp+8], AX
  135.  
  136. POP AX
  137. POP DX
  138. POP BP
  139.  
  140. ; Удаляем дубликат адреса возврата
  141. ADD SP, 02h
  142.  
  143. RET
  144.  
  145. PUTCH ENDP
  146. ;------------------------------------------------
  147. ; Вывод строки по адресу, переданному в стек
  148. PUTBY PROC
  149.  
  150. PUSH AX
  151. PUSH DX
  152. PUSH BP
  153.  
  154. MOV BP, SP
  155.  
  156. ; Выводим строку
  157. MOV AH, 09h
  158. MOV DX, OFFSET [bp+8]
  159. INT 21h
  160.  
  161. ; Пишем адрес возврата вместо адреса строки
  162. MOV AX, [bp+6]
  163. MOV [bp+8], AX
  164.  
  165. POP BP
  166. POP DX
  167. POP AX
  168.  
  169. ; Удаляем дубликат адреса возврата
  170. ADD SP, 02h
  171.  
  172. RET
  173.  
  174. PUTBY ENDP
  175. ;------------------------------------------------
  176. ; Перевод из HEX-числа в ASCII
  177. HEX PROC
  178.  
  179. PUSH BP
  180. PUSH AX
  181. PUSH BX
  182. PUSH DI
  183. PUSH ES
  184.  
  185. PUSH DS
  186. POP ES
  187.  
  188. MOV BP, SP
  189.  
  190. LEA DI, STRING
  191. LEA BX, TBL
  192. MOV AX, [BP+12]
  193.  
  194. PUSH AX
  195. SHR AL, 4
  196. XLAT
  197. STOSB
  198. POP AX
  199. PUSH AX
  200. AND AL, 0Fh
  201. XLAT
  202. STOSB
  203. POP AX
  204.  
  205. MOV AX, [BP+10]
  206. MOV [BP+12], AX
  207.  
  208. POP ES
  209. POP DI
  210. POP BX
  211. POP AX
  212. POP BP
  213.  
  214. ADD SP, 02h
  215.  
  216. RET
  217.  
  218. HEX ENDP
  219. ;------------------------------------------------
  220. PRINT_CONVERTED PROC
  221.  
  222. PUSH AX
  223. PUSH BX
  224. PUSH CX
  225. PUSH DX
  226. PUSH BP
  227. PUSH SI
  228.  
  229. MOV BP, SP
  230.  
  231. MOV CX, 8
  232. MOV AL, [bp+16]
  233. MOV SI, 0
  234.  
  235. ; Заполняем буфер для вывода
  236. PRINT_DEC_LOOP:
  237. MOV BL, [bp+14]
  238. MOV AH, 0
  239. DIV BL
  240. LEA BX, TBL
  241. XCHG AH, AL
  242. XLAT
  243. XCHG AL, AH
  244. MOV [DECSTR+SI], AH
  245. INC SI
  246. CMP AL, 0
  247. JE PRINT_DEC_END
  248. LOOP PRINT_DEC_LOOP
  249.  
  250. PRINT_DEC_END:
  251.  
  252. MOV CX, SI
  253.  
  254. ; Выводим представление числа
  255. PRINT_DEC_ECHO:
  256. MOV SI, CX
  257. MOV DL, [DECSTR+SI-1]
  258. MOV AH, 02h
  259. INT 21h
  260. LOOP PRINT_DEC_ECHO
  261.  
  262. MOV AX, [bp+12]
  263. MOV [bp+16], AX
  264.  
  265. POP SI
  266. POP BP
  267. POP DX
  268. POP CX
  269. POP BX
  270. POP AX
  271.  
  272. ADD SP, 04h
  273.  
  274. RET
  275.  
  276. PRINT_CONVERTED ENDP
  277. ;------------------------------------------------
  278. INPUT_NUM_SYS PROC
  279.  
  280. PUSH AX
  281. PUSH BX
  282. PUSH CX
  283.  
  284. PUSH OFFSET NUMMSG
  285. CALL PUTBY
  286.  
  287. CALL GETCH
  288. SUB AL, 30h ; Теперь в AL - первая цифра
  289. MOV AH, 0 ; Расширение до слова
  290. MOV BX, 10
  291. MOV CX, AX ; В CX - первая цифра
  292. NUM_SYS_LOOP:
  293. CALL GETCH
  294. CMP AL, ENDCHAR ; Ввели конец строки
  295. JE NUM_SYS_END ; Выходим из цикла
  296. SUB AL, 30h
  297. CBW ; Расширение до слова
  298. XCHG AX, CX
  299. MUL BX ; AX * 10
  300. ADD CX, AX ; CX = AX * 10 + CX
  301. JMP NUM_SYS_LOOP
  302.  
  303. NUM_SYS_END:
  304. MOV WORD PTR NUM_SYS, CX
  305. CALL CRLF
  306.  
  307. ; Если меньше 2 - выходим с ошибкой
  308. CMP CX, 1
  309. JLE ERROR_INPUT
  310. ; Если больше 16 - выходим с ошибкой
  311. CMP CX, 16
  312. JG ERROR_INPUT
  313.  
  314. NUM_SYS_INP_END:
  315. POP CX
  316. POP BX
  317. POP AX
  318.  
  319. RET
  320.  
  321. ERROR_INPUT:
  322. PUSH OFFSET ERRMSG
  323. CALL PUTBY
  324. CALL CRLF
  325. MOV ENDFLAG, 1
  326. JMP NUM_SYS_INP_END
  327.  
  328. INPUT_NUM_SYS ENDP
  329. ;------------------------------------------------
  330. MAIN PROC
  331.  
  332. PUSH AX
  333. PUSH CX
  334. PUSH DX
  335.  
  336. ; Выводим приглашение ввода
  337. PUSH OFFSET CPROMPT
  338. CALL PUTBY
  339. CALL CRLF
  340.  
  341. ; Вводим не более COUNT символов
  342. MOV CX, COUNT
  343.  
  344. ; Вввод символа с буферизацией в стек
  345. INPUT_LOOP:
  346. CALL GETCH
  347. CMP AL, ENDCHAR
  348. JE INPUT_END
  349. PUSH AX
  350. LOOP INPUT_LOOP
  351.  
  352. INPUT_END:
  353.  
  354. ; Получаем кол-во введенных символов
  355. MOV AX, CX
  356. MOV CX, COUNT
  357. SUB CX, AX
  358.  
  359. ; Проверяем условия выхода
  360. CMP CX, 0
  361. JE MAIN_END
  362. POP DX
  363. PUSH DX
  364. CMP DL, '*'
  365. JNE CONTINUE
  366. CMP CX, 1
  367. JNE CONTINUE
  368. MOV ENDFLAG, 1
  369. POP DX
  370. JMP MAIN_END
  371.  
  372. CONTINUE:
  373. ; Выводим кол-во введенных символов
  374. PUSH OFFSET BEF_LEN
  375. CALL PUTBY
  376. PUSH WORD PTR NUM_SYS
  377. MOV AX, 10
  378. PUSH AX
  379. CALL PRINT_CONVERTED
  380. PUSH OFFSET MID_LEN
  381. CALL PUTBY
  382. PUSH CX
  383. PUSH WORD PTR NUM_SYS
  384. CALL PRINT_CONVERTED
  385. PUSH OFFSET AFT_LEN
  386. CALL PUTBY
  387.  
  388. ; Устанавливаемся в конец массива байт
  389. MOV SI, BUFLEN
  390. SUB SI, 2
  391.  
  392. ; Заполняем в обратном порядке
  393. CONVERT_LOOP:
  394. CALL HEX
  395. MOV DL, [STRING+1]
  396. MOV [BUFFER+SI-0], DL
  397. MOV DL, [STRING+0]
  398. MOV [BUFFER+SI-1], DL
  399. MOV DL, ' '
  400. MOV [BUFFER+SI-2], DL
  401. SUB SI, 3
  402. LOOP CONVERT_LOOP
  403.  
  404. ; Окончательный вывод результата
  405. MOV AX, OFFSET BUFFER
  406. ADD AX, SI
  407. ADD AX, 2
  408. PUSH AX
  409. CALL PUTBY
  410.  
  411. MAIN_END:
  412. POP DX
  413. POP CX
  414. POP AX
  415. RET
  416.  
  417. MAIN ENDP
  418. ;------------------------------------------------
  419. ; ОСНОВНАЯ ТОЧКА ВХОДА
  420. ;------------------------------------------------
  421. BODY:
  422.  
  423. ; Установка сегмента данных
  424. PUSH CS
  425. POP DS
  426.  
  427. ; Очищаем экран
  428. CALL CLRSCR
  429.  
  430. ; Вводим основание системы счисления для вывода
  431. CALL INPUT_NUM_SYS
  432. MOV AL, ENDFLAG
  433. CMP AL, 1
  434. JE BODY_END
  435.  
  436. ; Вводим строки для перевода
  437. MAIN_LOOP:
  438. CALL MAIN
  439. CALL CRLF
  440. MOV AL, ENDFLAG
  441. CMP AL, 1
  442. JE BODY_END
  443. JMP MAIN_LOOP
  444.  
  445. ; Прощальный вывод
  446. BODY_END:
  447. PUSH OFFSET ENDMSG
  448. CALL PUTBY
  449. PUSH OFFSET OUTMSG
  450. CALL PUTBY
  451. CALL CRLF
  452.  
  453. ; Завершение работы программы
  454. MOV AX, 4C00h ; Аналогично MOV AH, 4Ch
  455. INT 21h
  456.  
  457. CODE_SEG ENDS
  458. ;------------------------------------------------
  459. END START
  460. ;------------------------------------------------
Add Comment
Please, Sign In to add comment