Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;------------------------------------------------
- ; ЛАБОРАТОРНАЯ РАБОТА ПО СП №5
- ; "Ввод и вывод в машинном формате"
- ;================================================
- ; Разработал: Михаил Кучеренко, ИУ5-44, 2018 г.
- ;------------------------------------------------
- ; Компилить: run.bat SP_Lab5 COM
- ;------------------------------------------------
- CODE_SEG SEGMENT PARA PUBLIC 'CODE'
- ASSUME DS:CODE_SEG, CS:CODE_SEG, SS:CODE_SEG
- ORG 100h
- ;------------------------------------------------
- START:
- JMP BODY
- ;------------------------------------------------
- ; ДАННЫЕ
- ;------------------------------------------------
- ; Максимальное количество символов в строке
- COUNT DW 20
- ; Буфер для вывода
- BUFFER DB 60 dup('$'), "$"
- ; Длина буферной строки
- BUFLEN EQU $-BUFFER
- ; Символ, завершающий ввод (сейчас - enter)
- ENDCHAR DB 0Dh
- ; Таблица перекодировки
- TBL DB "0123456789ABCDEF"
- ; Массив для перекодировки HEX
- STRING DB 4 dup('$'), "$"
- ; Массив для перекодировки PRINT_CONVERTED
- DECSTR DB 8 dup('X'), "$"
- ; Кусочки строки для красивого вывода
- BEF_LEN DB " (В $"
- MID_LEN DB " с/с: $"
- AFT_LEN DB ") = $"
- ; Основание системы счисления для вывода
- NUM_SYS DB ?
- ; Программные уведомления
- ERRMSG DB " [ERROR] Неверное основание системы счисления!$"
- NUMMSG DB "Введите систему счисления для вывода длины строки: $"
- CPROMPT DB "Введите строку для конвертации или '*', чтобы выйти: $"
- ENDMSG DB "Завершение программы ...",0Dh,0Ah,"$"
- OUTMSG DB "Автор: Михаил Кучеренко, ИУ5-44$"
- ; Флаг начала процедуры завершения работы
- ENDFLAG DB 0
- ;------------------------------------------------
- ; ПРОЦЕДУРЫ
- ;------------------------------------------------
- ; Очистка экрана
- CLRSCR PROC
- PUSH AX
- MOV AX, 03h
- INT 10h
- POP AX
- RET
- CLRSCR ENDP
- ;------------------------------------------------
- ; Вывод перевода сроки
- CRLF PROC
- PUSH 0Dh ; Выводим CR
- CALL PUTCH
- PUSH 0Ah ; Выводим LF
- CALL PUTCH
- RET
- CRLF ENDP
- ;------------------------------------------------
- ; Ввод одного символа с клавиатуры
- GETCH PROC ; Неявно использует AX
- PUSH DX
- ; Ожидание ввода символа
- MOV AH, 08h
- INT 21h
- ; Игнорируем символы конца строки и enter
- CMP AL, '$'
- JE GetchEnd
- CMP AL, 0Dh
- JE GetchEnd
- ; Выводим остальное
- MOV AH, 02h
- MOV DL, AL
- INT 21h
- ; Если backspace - заменяем предыдущий символ
- CMP AL, 08h
- JNE GetchEnd
- MOV AH, 02h
- MOV DL, ' '
- INT 21h
- MOV DL, 08h
- INT 21h
- GetchEnd:
- POP DX
- RET
- GETCH ENDP
- ;------------------------------------------------
- ; Вывод одного символа, переданного в стек
- PUTCH PROC
- PUSH BP
- PUSH DX
- PUSH AX
- ; Получаем положение вершины стека
- MOV BP, SP
- ; Выводим символ из стека
- MOV AH, 02h
- MOV DL, [bp+8]
- ;MOV DL, 48h
- INT 21h
- ; Пишем адрес возврата вместо символа
- MOV AX, [bp+6]
- MOV [bp+8], AX
- POP AX
- POP DX
- POP BP
- ; Удаляем дубликат адреса возврата
- ADD SP, 02h
- RET
- PUTCH ENDP
- ;------------------------------------------------
- ; Вывод строки по адресу, переданному в стек
- PUTBY PROC
- PUSH AX
- PUSH DX
- PUSH BP
- MOV BP, SP
- ; Выводим строку
- MOV AH, 09h
- MOV DX, OFFSET [bp+8]
- INT 21h
- ; Пишем адрес возврата вместо адреса строки
- MOV AX, [bp+6]
- MOV [bp+8], AX
- POP BP
- POP DX
- POP AX
- ; Удаляем дубликат адреса возврата
- ADD SP, 02h
- RET
- PUTBY ENDP
- ;------------------------------------------------
- ; Перевод из HEX-числа в ASCII
- HEX PROC
- PUSH BP
- PUSH AX
- PUSH BX
- PUSH DI
- PUSH ES
- PUSH DS
- POP ES
- MOV BP, SP
- LEA DI, STRING
- LEA BX, TBL
- MOV AX, [BP+12]
- PUSH AX
- SHR AL, 4
- XLAT
- STOSB
- POP AX
- PUSH AX
- AND AL, 0Fh
- XLAT
- STOSB
- POP AX
- MOV AX, [BP+10]
- MOV [BP+12], AX
- POP ES
- POP DI
- POP BX
- POP AX
- POP BP
- ADD SP, 02h
- RET
- HEX ENDP
- ;------------------------------------------------
- PRINT_CONVERTED PROC
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH BP
- PUSH SI
- MOV BP, SP
- MOV CX, 8
- MOV AL, [bp+16]
- MOV SI, 0
- ; Заполняем буфер для вывода
- PRINT_DEC_LOOP:
- MOV BL, [bp+14]
- MOV AH, 0
- DIV BL
- LEA BX, TBL
- XCHG AH, AL
- XLAT
- XCHG AL, AH
- MOV [DECSTR+SI], AH
- INC SI
- CMP AL, 0
- JE PRINT_DEC_END
- LOOP PRINT_DEC_LOOP
- PRINT_DEC_END:
- MOV CX, SI
- ; Выводим представление числа
- PRINT_DEC_ECHO:
- MOV SI, CX
- MOV DL, [DECSTR+SI-1]
- MOV AH, 02h
- INT 21h
- LOOP PRINT_DEC_ECHO
- MOV AX, [bp+12]
- MOV [bp+16], AX
- POP SI
- POP BP
- POP DX
- POP CX
- POP BX
- POP AX
- ADD SP, 04h
- RET
- PRINT_CONVERTED ENDP
- ;------------------------------------------------
- INPUT_NUM_SYS PROC
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH OFFSET NUMMSG
- CALL PUTBY
- CALL GETCH
- SUB AL, 30h ; Теперь в AL - первая цифра
- MOV AH, 0 ; Расширение до слова
- MOV BX, 10
- MOV CX, AX ; В CX - первая цифра
- NUM_SYS_LOOP:
- CALL GETCH
- CMP AL, ENDCHAR ; Ввели конец строки
- JE NUM_SYS_END ; Выходим из цикла
- SUB AL, 30h
- CBW ; Расширение до слова
- XCHG AX, CX
- MUL BX ; AX * 10
- ADD CX, AX ; CX = AX * 10 + CX
- JMP NUM_SYS_LOOP
- NUM_SYS_END:
- MOV WORD PTR NUM_SYS, CX
- CALL CRLF
- ; Если меньше 2 - выходим с ошибкой
- CMP CX, 1
- JLE ERROR_INPUT
- ; Если больше 16 - выходим с ошибкой
- CMP CX, 16
- JG ERROR_INPUT
- NUM_SYS_INP_END:
- POP CX
- POP BX
- POP AX
- RET
- ERROR_INPUT:
- PUSH OFFSET ERRMSG
- CALL PUTBY
- CALL CRLF
- MOV ENDFLAG, 1
- JMP NUM_SYS_INP_END
- INPUT_NUM_SYS ENDP
- ;------------------------------------------------
- MAIN PROC
- PUSH AX
- PUSH CX
- PUSH DX
- ; Выводим приглашение ввода
- PUSH OFFSET CPROMPT
- CALL PUTBY
- CALL CRLF
- ; Вводим не более COUNT символов
- MOV CX, COUNT
- ; Вввод символа с буферизацией в стек
- INPUT_LOOP:
- CALL GETCH
- CMP AL, ENDCHAR
- JE INPUT_END
- PUSH AX
- LOOP INPUT_LOOP
- INPUT_END:
- ; Получаем кол-во введенных символов
- MOV AX, CX
- MOV CX, COUNT
- SUB CX, AX
- ; Проверяем условия выхода
- CMP CX, 0
- JE MAIN_END
- POP DX
- PUSH DX
- CMP DL, '*'
- JNE CONTINUE
- CMP CX, 1
- JNE CONTINUE
- MOV ENDFLAG, 1
- POP DX
- JMP MAIN_END
- CONTINUE:
- ; Выводим кол-во введенных символов
- PUSH OFFSET BEF_LEN
- CALL PUTBY
- PUSH WORD PTR NUM_SYS
- MOV AX, 10
- PUSH AX
- CALL PRINT_CONVERTED
- PUSH OFFSET MID_LEN
- CALL PUTBY
- PUSH CX
- PUSH WORD PTR NUM_SYS
- CALL PRINT_CONVERTED
- PUSH OFFSET AFT_LEN
- CALL PUTBY
- ; Устанавливаемся в конец массива байт
- MOV SI, BUFLEN
- SUB SI, 2
- ; Заполняем в обратном порядке
- CONVERT_LOOP:
- CALL HEX
- MOV DL, [STRING+1]
- MOV [BUFFER+SI-0], DL
- MOV DL, [STRING+0]
- MOV [BUFFER+SI-1], DL
- MOV DL, ' '
- MOV [BUFFER+SI-2], DL
- SUB SI, 3
- LOOP CONVERT_LOOP
- ; Окончательный вывод результата
- MOV AX, OFFSET BUFFER
- ADD AX, SI
- ADD AX, 2
- PUSH AX
- CALL PUTBY
- MAIN_END:
- POP DX
- POP CX
- POP AX
- RET
- MAIN ENDP
- ;------------------------------------------------
- ; ОСНОВНАЯ ТОЧКА ВХОДА
- ;------------------------------------------------
- BODY:
- ; Установка сегмента данных
- PUSH CS
- POP DS
- ; Очищаем экран
- CALL CLRSCR
- ; Вводим основание системы счисления для вывода
- CALL INPUT_NUM_SYS
- MOV AL, ENDFLAG
- CMP AL, 1
- JE BODY_END
- ; Вводим строки для перевода
- MAIN_LOOP:
- CALL MAIN
- CALL CRLF
- MOV AL, ENDFLAG
- CMP AL, 1
- JE BODY_END
- JMP MAIN_LOOP
- ; Прощальный вывод
- BODY_END:
- PUSH OFFSET ENDMSG
- CALL PUTBY
- PUSH OFFSET OUTMSG
- CALL PUTBY
- CALL CRLF
- ; Завершение работы программы
- MOV AX, 4C00h ; Аналогично MOV AH, 4Ch
- INT 21h
- CODE_SEG ENDS
- ;------------------------------------------------
- END START
- ;------------------------------------------------
Add Comment
Please, Sign In to add comment