Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SP_Lab_1.doc
Скачиваний:
3
Добавлен:
18.08.2019
Размер:
361.47 Кб
Скачать

Лабораторная работа №5 ввод с клавиатуры и обработка символьных строк (пароль) Теоретические сведения

Для ввода строки символов можно пользоваться специальной функцией 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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]