- •О десский национальный морской университет
- •7.080401 "Информационные управляющие системы и технологии",
- •7.080402 "Информационные технологии проектирования"
- •Введение
- •Лабораторная работа №1 структура ехе-программы на ассемблере. Подготовка к выполнению Теоретические сведения
- •Задание
- •Лабораторная работа №2 использование служебных подпрограмм. Циклы. Формирование и вывод на экран строки ascii- символов Теоретические сведения
- •Inc al ; увеличиваем al (код символа) на 1
- •Задание
- •Лабораторная работа №3 управление курсором при выводе. Вложенные циклы. Формирование и вывод на экран таблицы символов ascii Теоретические сведения
- •Задание
- •Лабораторная работа №4 посимвольный ввод с клавиатуры. Анализ нажатия функциональных клавиш и комбинаций Теоретические сведения
- •Задание
- •Лабораторная работа №5 ввод с клавиатуры и обработка символьных строк (пароль) Теоретические сведения
- •Задание
- •Лабораторная работа №6 процедуры. Табличная трансляция. Перевод двоичных данных в символьную форму Теоретические сведения
- •Задание
- •Лабораторная работа №7 работа с файлами Теоретические сведения
- •Задание
Лабораторная работа №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