Глава 16 - практика: циклы и ввод с клавиатуры
Мы используем cookie-файлы, чтобы получить статистику, которая помогает нам улучшить сервис для Вас с целью персонализации сервисов и предложений. Вы можете прочитать подробнее о cookie-файлах или изменить настройки браузера. Продолжая пользоваться сайтом без изменения настроек, вы даёте согласие на использование ваших cookie-файлов.
speech bubble

Глава 16 - практика: циклы и ввод с клавиатуры

Самоучитель по языку ассемблер(assembler)

 

Содержание:

 

ВНИМАНИЕ! Данный самоучитель был написан много лет назад и его автор не сможет ответить на ваши вопросы. Курс по assembler предназначен для саморазвития. Если у вас хватает квалификации, можете предложить внести правки.

 

Способы ввода данных с клавиатуры

Процесс ввода информации в ассемблерных программах осуществляется аналогично выводу. Ниже описан ряд функций прерывания 21h, использующихся для ввода информации с клавиатуры.

Функция 01h
Ввод с клавиатуры.
Вход: AH=01h
Выход: AL= символ, полученный с клавиатуры

Описание: Считывает (ожидает) символ со стандартного входного устройства. Отображает этот символ на стандартное выходное устройство (эхо). Ввод расширенных клавиш ASCII (F1-F12, PgUp, курсор и т.п.) требует двух обращений к этой функции. Первый вызов возвращает AL=0. Второй вызов возвращает в AL расширенный код ASCII.

Функция 07h
Не фильтрующий консольный ввод без эха.
Вход: AH=07h
Выход: AL= символ, полученный с клавиатуры

Описание: Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. Не фильтрует: Не проверяет на Ctrl-Break, backspace и т.п. Необходимо вызывать дважды для ввода расширенного символа ASCII.

Функция 08h
Консольный ввод без эха.
Вход: AH=08h
Выход: AL= символ, полученный с клавиатуры

Описание: Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. При обнаружении Ctrl-Break выполняется прерывание INT 23H. Необходимо вызывать дважды для ввода расширенного символа ASCII.

Функция 0ah
Буферизированный ввод строки.
Вход: AH=0ah
DS:DX=адрес входного буфера (смотри ниже)
Выход: буфер содержит ввод, заканчивающийся символом CR (ASCII 0dH)

Описание: При входе буфер по адресу DS:DX должен быть оформлен следующим образом:
max ? ? ? ? ? ? …
MAX - максимально допустимая длина ввода (от 1 до 254) При выходе буфер заполнен данными следующим образом:
max len T E X T … 0dh

LEN - действительная длина данных без завершающего CR (здесь – 0dH). Символы считываются со стандартного ввода вплоть до CR (ASCII 0dH) или до достижения длины MAX-1. Если достигнут MAX-1, включается консольный звонок для каждого очередного символа, пока не будет введен возврат каретки CR (нажатие Enter). Второй байт буфера заполняется действительной длиной введенной строки, не считая завершающего CR. Последний символ в буфере -всегда CR (который не засчитан в байте длины). Символы в буфере (включая LEN) в момент вызова используются как "шаблон". В процессе ввода действительны обычные клавиши редактирования: Esc выдает "\" и начинает с начала, F3 выдает буфер до конца шаблона, F5 выдает "@" и сохраняет текущую строку как шаблон, и т.д. Большинство расширенных кодов ASCII игнорируются. При распознавании Ctrl-Break выполняется прерывание INT 23H (буфер остается неизменным).

Функция 0ch
Ввод с очисткой
Вход: AH=0ch
AL= номер функции ввода DOS (01H, 06H, 07H, 08H или 0aH)
Выход: нет

Описание: Очищает буфер опережающего ввода стандартного ввода, а затем вызывает функцию ввода, указанную в AL. Это заставляет систему ожидать ввод очередного символа. Следующие значения допустимы в AL: 01H Ввод с клавиатуры; 06H Ввод с консоли; 07H Не фильтрующий без эха; 08H Ввод без эха; 0aH Буферизованный ввод.

 

Примеры программ

Далее программы будут оформляться в виде COM.

Рассмотрим программу которая осуществляет ввод строки с клавиатуры и заменяет все буквы "а" на заглавные, причем пробелы удаляются.

Файл inpstr.asm:

.model tiny
.code
org 100h
start:
;выводим приглашение
mov dx,offset message
mov ah,09h
int 21h
;вводим строку
mov ah,0Ah
mov dx,offset inpstr
int 21h
;выводим то что ввели
mov dx,offset inpstr+2
mov ah,09h
int 21h
;начинаем цикл обработки
;с индекса 2 в массиве начинается введенная инфа
mov si,2
;нулевое смещение для преобразованной строки
mov di,0
;по индексу 1 в массиве находится длинна
mov cl, byte ptr [inpstr+1]
;теперь в cx длинна - для цикла
mov ch,0
;сам цикл
lop: mov ah,inpstr[si]
;сравниваем элемент строки с буквой "а"
cmp ah,'a'
jne met
;пишем в новую строку заглавную A
mov dl,'A'
mov sn[di],dl
;увеличиваем индекс для новой строки
inc di
jmp met1
;пробелы пропускаем!
met: cmp ah,' '
je met1
;это не "а" и не пробел- поэтому просто переносим букву в новую строку
mov sn[di],ah
inc di
;увеличим индекс для следующего элемента исходной строки
met1: inc si
;цикл пока не переберём все элементы строки
loop lop
;выводим сообщение
mov dx,offset message2
mov ah,09h
int 21h
;выводим исправленную строку
mov dx,offset sn
mov ah,09h
int 21h
ret
message db 'Please, input string:',0Ah,0Dh,'$'
message2 db 'It is new string:',0Ah,0Dh,'$'
;строка которую мы введём
inpstr db 10,?,10 dup ('$'),0Ah,0Dh,'$'
;новая строка
sn db 10 dup ('$'),0Ah,0Dh,'$'
end start

Компиляция:

c:\specprog\tasm\bin\tasm.exe inpstr.bat
c:\specprog\tasm\bin\tlink.exe inpstr.obj /t/x

Результат запуска:

 

Для комментирования необходимо авторизоваться