- •Глава 12
- •Пересылка цепочек
- •Команда movs
- •Пересылка байтов, слов и двойных слов
- •Сравнение цепочек
- •Команда cmps
- •Сравнение байтов, слов и двойных слов
- •Сканирование цепочек
- •Команда scas
- •Сканирование строки байтов, слов, двойных слов
- •Загрузка элемента цепочки в аккумулятор
- •Команда lods
- •Загрузка в регистр al/ax/eax байтов, слов, двойных слов
- •Перенос элемента из аккумулятора в цепочку
- •Команда stos
- •Сохранение в цепочке байта, слова, двойногослова из регистра al/ax/eax
- •Работа с портами ввода-вывода
- •Ввод элемента цепочки из порта ввода-вывода
- •Вывод элемента цепочки в порт ввода-вывода
Сравнение байтов, слов и двойных слов
Так же как и в группе команд пересылки цепочки, в группе команд сравнения есть отдельные команды для сравнения цепочек байтов, слов, двойных слов — CMPSB, CMPSW и CMPSD соответственно. Для этих команд все рассуждения аналогичны тем,
что были приведены при описании команд пересылки. Ассемблер преобразует команду CMPS в одну из машинных команд, CMPSB, CMPSW или CMPSD, в зависимости от размера элементов сравниваемых цепочек.
Сканирование цепочек
Команды, реализующие операцию-примитив сканирования цепочек, производят поиск некоторого значения в области памяти. Логически эта область памяти рассматривается как последовательность (цепочка) элементов фиксированной длины размером 8, 16 или 32 бита. Искомое значение предварительно должно быть помещено в один из регистров AL/AX/EAX. Выбор конкретного регистра из этих трех должен быть согласован с размером элементов цепочки, в которой осуществляется поиск. Система команд процессора предоставляет программисту четыре команды сканирования цепочки. Выбор конкретной команды определяется размером элемента:
SCAS адрес_приемника — сканировать цепочку (SCAning String);
SCASB — сканировать цепочку байтов (SCAning String Byte);
SCASW — сканировать цепочку слов (SCAning String Word);
SCASD — сканировать цепочку двойных слов (SCAning String Double Word).
Команда scas
Синтаксис команды SCAS:
seas адрес__приемника
Команда имеет один операнд, обозначающий местонахождение цепочки в дополнительном сегменте (адрес цепочки должен быть заранее сформирован в регистрах ES:EDI/DI). Транслятор анализирует тип идентификатора адрес_приемника, который обозначает цепочку в сегменте данных, и формирует одну из трех машинных команд, SCASB, SCASW или SCASD. Условие поиска для каждой из этих трех команд находится в строго определенном месте. Так, если цепочка описана с помощью директивы DB, то искомый элемент должен быть байтом, находиться в регистре AL, и сканирование цепочки осуществляется командой SCASB. Если цепочка описана спомощью директивы DW, то это — слово в регистре АХ, и поиск ведется командой SCASW. Если цепочка описана с помощью директивы DD, то это — двойное слово в ЕАХ, и поиск ведется командой SCASD. Принцип поиска тот же, что и в команде сравнения CMPS, то есть последовательное выполнение вычитания (содержимое регистра аккумулятора минус содержимое очередного элемента цепочки). В зависимости от результатов вычитания производится установка флагов, при этом сами операнды не изменяются. Так же как и в случае команды CMPS, с командой SCAS удобно использовать префиксы REPE/REPZ или REPNE/REPNZ.
REPE или REPZ — если нужно организовать поиск до тех пор, иока не будет выполнено одно из двух условий:
-будет достигнут конец цепочки (содержимое ЕСХ/СХ равно 0);
- в цепочке встретится элемент, отличный от элемента в регистре AL/AX/EAX.
REPNE или REPNZ — если нужно организовать поиск до тех пор, пока не будет выполнено одно из двух условий:
-будет достигнут конец цепочки (содержимое ЕСХ/СХ равно 0);
-в цепочке встретится элемент, совпадающий с элементом в регистре AL/AX/EAX.
Таким образом, команда SCAS с префиксом REPE/REPZ позволяет найти элемент цепочки, отличающийся по значению от заданного в аккумуляторе. Команда SCAS
с префиксом REPNE/REPNZ позволяет найти элемент цепочки, совпадающий по значению с элементом в аккумуляторе. В качестве примера рассмотрим листинг 12.3, в котором реализован поиск символа в строке. В программе используется команда-примитив SCAS. Символ задается явно (строка 20). Префикс повторения -REPNE.
Листинг 12.3. Поиск символа в строке командой SCAS
;prg_12_3.asm
MASM
MODEL small
STACK 256
.data
; тексты сообщений
fnd db 0ah,0dh,'Символ найден! ","$'
nochar db Oah,0dh,'Символ не найден.','$'
;строка для поиска
string db "Поиск символа в этой строке.",Oah,0dh,'$'
.code
ASSUME ds:@data,es:@data
main:
mov ax,@data
mov ds,ax
mov es.ax ;настройка ES на DS
mov ah,09h
lea dx,string
int 21h ;вывод сообщения string
mov al.'a' ;символ для поиска - "а"(кириллица)
eld ;сброс флага df
lea di,string ;загрузка в es:di смещения строки
mov ex,28 ;для префикса repne - длина строки
;поиск в строке (пока искомый символ и символ в строке не совпадут)
;выход при первом совпадении
repne seas string
je found ;если равны - переход на обработку,
failed: ;иначе - выполняем некоторые действия
;вывод сообщения о том, что символ не найден
mov ah,Q9h
lea dx,nochar
int 21h ;вывод сообщения nochar
jmp exit ;на выход
found: ;совпали
mov ah,Q9h
lea dx.fnd
int 21h ;вывод сообщения fnd
;теперь, чтобы узнать место, где совпал элемент в строке,
;необходимо уменьшить значение в регистре di и вставить нужный обработчик
; dec di
;... вставьте обработчик
exit: ;выход
mov ax,4c00h
int 21h
end main
