ВВОД С КЛАВИАТУРЫ И ОБРАБОТКА СИМВОЛЬНЫХ СТРОК (ПАРОЛЬ)



Теоретические сведения

Для ввода строки символов можно пользоваться специальной функцией DOS — 0Ah int 21h (буферизованный ввод). Она обеспечивает ввод в буфер строки символов с клавиатуры с эхом на экран, обрабатывает управляющие коды и Ctrl-Break, завершает ввод по нажатию Enter. На входе AH = 0Ah, DS:DX = адрес подготовленного буфера, в первом байте которого указана максимальная длина вводимой строки; на выходе второй байт буфера заполнен реальной длиной введенной строки, а следующие байты содержат введенные символы.

Эта функция хорошо подходит для простых задач. Она обладает рядом удобств: интерпретирует управляющие клавиши: BackSpace — стирание последнего символа, ESC — ввод сначала и др., обеспечивает эхо на экран, позволяет просто ограничить длину вводимой строки и возвращает ее реальную длину. Однако в тех случаях, когда требуется особым образом программировать эхо на экран и обработку вводимых данных по мере ввода, необходимо программировать цикл с посимвольным вводом.

Для обработки строк бывает удобно воспользоваться строковыми командами. Они предназначены для обработки последовательностей байтов или слов в памяти. Каждая из этих команд сама по себе обрабатывает один элемент строки. Команда, однако, может предваряться специальным префиксом повторения, что вызывает последовательную обработку элементов строки в аппаратном цикле. Строки обрабатываются при этом намного быстрее, чем при организации стандартного программного цикла. Могут использоваться разновидности префикса повторения, обеспечивающие досрочное завершение обработки при выполнении определенных условий.

В группу строковых команд входят пять основных команд: пересылка, сравнение, сканирование, загрузка в аккумулятор и сохранение в памяти (см. табл. ниже). Каждая из них представлена тремя модификациями. Первая модификация требует использования операндов — имен сравниваемых строк. Указанные имена (точнее, их типы — байтовый или словный) используются для определения размера элементов строк. Две другие модификации используются без операндов, причем буква B в мнемонике команды указывает на обработку байтов, а W — на обработку слов. Часто строковые команды используются для обработки строк символов.

 

Форматы команд Выполняемое действие Примечание
1 Пересылка строки  MOVS op1,op2  MOVSB  MOVSW Скопировать элемент строки-источника в элемент строки-приемника, затем модифицировать указатели SI и DI.  
2 Сравнение строк  CMPS op1,op2  CMPSB  CMPSW Сравнить элементы строки-источника и строки-приемника, сформировав соот-ветствующие значения флагов, затем модифицировать указатели SI и DI. вычитание [SI]-[DI] без сохранения результата
3 Сканирование строки  SCAS op1  SCASB  SCASW Сравнить элемент строки-приемника со значением аккумулятора, сформировав соответствующие значения флагов, затем модифицировать указатель DI. вычитание Аккумулятор-[DI] без сохранения результата
4 Загрузка в аккумулятор  LODS op1  LODSB  LODSW Скопировать элемент строки-источника в аккумулятор (AL или AX), затем модифицировать указатель SI.  
5 Сохранение в памяти  STOS op1  STOSB  STOSW Скопировать значение аккумулятора (AL или AX) в элемент строки-приемника, затем модифицировать указатель DI.  

 

При использовании строковых команд используются термины "строка-источник" и "строка-приемник". Например, при пересылке данных элементы строки-источника копируются в строку-приемник, а при сканировании сканируется строка-приемник и т. п. Предполагается, что строка-источник размещена в сегменте данных (адрес которого находится в регистре DS), а строка-приемник — в дополнительном сегменте (с адресом в регистре ES). Относительный адрес строки-источника должен находиться в регистре SI (Source Index), а строки-приемника — в регистре DI (Destination Index). Перед использованием непосредственно строковой команды необходимо заполнить указанные регистры необходимыми значениями адресов. Это необходимо делать также и при использовании вариантов строковых команд с операндами. Если обе обрабатываемые строки находятся в одном сегменте программы, необходимо настроить регистры DS и ES на начало этого сегмента.

Так как строковые команды предназначены для обработки группы элементов, они автоматически выполняют модификацию регистров-указателей SI и DI после каждого выполненного действия (на 1 при обработке байтов и на 2 при обработке слов), обеспечивая тем самым продвижение по строке. Флаг направления DF определяет направление этого продвижения: при DF = 0 значения указателей увеличиваются (продвижение "вперед"), а при DF = 1 — уменьшаются ("назад"). Состоянием этого флага можно управлять с помощью команд CLD (сбросить флаг DF) и STD (установить флаг DF).

Автоматическое повторение строковых команд осуществляется при использовании префикса повторения REP (от "repeat"), указываемого непосредственно перед строковой командой. Как и в LOOP-циклах, количество повторений (то есть обрабатываемых элементов) необходимо предварительно занести в регистр СХ; эта величина автоматически уменьшается на 1 после каждого выполнения команды. Когда значение СХ становится равным нулю, аппаратный цикл завершается, и управление переходит к следующей команде в памяти.

Префиксы REPE (синоним REPZ) и REPNE (REPNZ) позволяют "досрочно" (до исчерпания содержимого СХ) завершить циклическую обработку строки и применяются совместно с командами сравнения и сканирования. Первый префикс обеспечивает повторение команды, пока флаг ZF = 1 и CX ¹ 0 (REPeat if Equal — повторять, пока равно), а второй — пока флаг ZF = 0 и CX ¹ 0 (REPeat if Not Equal — повторять, пока не равно). При их использовании, как правило, за строковой командой следует команда условного перехода, позволяющая выяснить причину выхода из аппаратного цикла и передать управление соответствующей ветви программы. Индексные регистры SI и DI после выхода из цикла указывают на следующие элементы, не подвергавшиеся обработке (сравнению), а СХ содержит количество элементов, не подвергнутых обработке.

Перечислим практические варианты применения строковых команд.

Назначение команды MOVS достаточно очевидно — в сочетании с префиксом REP она используется для копирования строки из одного места памяти в другое. Необходимо обращать внимание на относительное расположение строки-источника и буфера-приемника и на их длины, так как возможно наложение строк.

Команда CMPS с префиксом REPE используется для проверки строк на полное совпадение (совпадение каждой соответствующей пары элементов строк), а с префиксом REPNE — для проверки строк на абсолютное несовпадение (несовпадение каждой соответствующей пары элементов строк).

Команда SCAS с префиксом REPNE используется для поиска в строке определенного элемента, а с префиксом REPE — для поиска в строке элемента, отличного от заданного (если такой элемент не найден, то, разумеется, строка составлена из одинаковых элементов).

Команда LODS используется без префиксов повторения для загрузки элемента строки-источника в регистр-аккумулятор. Для обработки строки команда LODS включается в обычный цикл.

Команда STOS используется для записи элемента из аккумулятора в строку-приемник. Часто она включается в цикл вместе с командой LODS для последовательной обработки элементов строки. Использование же команды STOS с префиксом REP приводит к заполнению строки-приемника значением аккумулятора и может использоваться для инициализации (например, очистки) строки.

Ниже приведен пример, иллюстрирующий использование функции 0Ah для ввода строки-пароля и строковой команды CMPSB для ее сравнения с паролем-эталоном.

 

; Данные в сегменте my_data

user_buf db 17, ?, 'место для пароля'

std_pwd db 'standard' ; эталонный пароль

std_len = $-std_pwd ; его длина

ok_mes db 13, 10, 'Верно$'

 

; Код

begin: mov ax, my_data

      mov ds, ax   ; подготовка сегментов данных

      mov es, ax

; ввод пароля

input: mov ah, 0Ah  ; буферизованный ввод строки

      lea dx, user_buf

      int 21h

; сравнение строк

      mov cx, std_len ; число симолов для сравнения

      lea si, std_pwd ; адреса сравниваемых

      lea di, user_buf+2 ; строк

      cld             ; направление обработки строк - вперед

repe  cmpsb

      jne input    ; если не совпали - на повторный ввод

ok:   mov ah, 9    ; если совпали - вывод сообщения

      lea dx, ok_mes ; 'Верно' с новой строки

      int 21h

Задание

Задать в программе исходный пароль; обеспечить вывод приглашения к вводу пароля; собственно ввод пользователем пароля с клавиатуры; сравнение строк исходного и введенного паролей; в случае точного совпадения выдать сообщение "Ok"; иначе бесконечно повторять запрос на ввод пароля. Обеспечить возможность прерывания ввода по Ctrl-C. При необходимости предусмотреть вывод диагностических сообщений. Обработку строк производить при помощи строковых команд.

 

Варианты:

1. Обеспечить при вводе пароля отображение звездочек (*) вместо вводимых символов. В случае, если ни одна из букв не набрана верно, выдать сообщение "Строки полностью различны".

2. Ограничить число попыток ввода пароля до трех. Перед вводом пользовательского пароля указывать количество оставшихся попыток. Выдать сообщение "Ok", если набраны верно хотя бы первые четыре буквы.

3. Зашифровать эталонный пароль так, чтобы его нельзя было сразу узнать из EXE-файла. Перед сравнением расшифровать эталонный пароль.

4. Подавить отображение символов на экране (эхо) при вводе пароля. При неравенстве длин введенного и эталонного паролей выдать сообщение "Введенная строка длиннее (короче) правильного пароля на N символов".

5. Обеспечить при вводе пароля отображение решеток (#) вместо вводимых символов. До побайтового сравнения строк сканировать введенную строку на определенный символ, присутствующий в правильном пароле (например, "s"), при его отсутствии строки не сравнивать и выдать сообщение "Неверный формат пароля".

6. Ввести ограничение на допустимые в пароле символы (например, только строчные латинские символы), при попытке ввода других символов выдавать звуковой сигнал (не прерывая ввода). Сравнение строк производить в обратном направлении.

7. Обеспечить возможность удаления неверно введенного символа нажатием клавиши BackSpace. Задать пароль строчными латинскими буквами; выдать перед запросом пароля сообщение "Вводимый пароль должен содержать только буквы английского алфавита. Прописные и строчные буквы не различаются". Перед сравнением строк привести буквы введенной строки к нижнему регистру.

8. Задать в программе три эталонных пароля и сравнить введенную строку с каждым из них. При вводе пароля скрыть вводимые символы.

9. После неудачного сравнения строк выдать номер первого отличного символа ("По крайней мере N-й символ введенной строки неверен").

10. Запросить вначале login (имя пользователя), а затем пароль. При вводе пароля не отображать вводимые символы. Выдать сообщение "Ok", если введенное имя совпадает с заданным, а также если введенный пароль является частью эталонного пароля.

11. Выдать сообщение "Ok", если введенная строка составлена из тех же символов, что и введенный пароль.

12. Выдать также сообщение "Ok", если введенная строка набрана задом наперед.

13. Задать эталонную строку из нескольких слов, разделенных пробелами. Если количество слов в введенной строке и заданной не совпадает, выдать количество введенных слов.

14. Задать в качестве пароля серийный номер в формате ХХХ.ХХХ.ХХХ (Х — любой символ). До полного сравнения строк проверить, имеются ли во введенном серийном номере точки в нужных местах. Если нет, строки не сравнивать и выдать сообщение "Неверный формат серийного номера".

Лабораторная работа №6


Дата добавления: 2018-04-05; просмотров: 408; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!