Операция сканирования цепочек

Команды, реализующие эту операцию-примитив, производят поиск некоторого значения в области памяти. Логически эта область памяти рассматривается как последовательность (цепочка) элементов фиксированной длины размером 8, 16 или 32 бит. Искомое значение предварительно должно быть помещено в регистр al/ax/eax. Выбор конкретного регистра из этих трех должен быть согласован с размером элементов цепочки, в которой осуществляется поиск.

Система команд микропроцессора предоставляет программисту четыре команды сканирования цепочки. Выбор конкретной команды определяется размером элемента:

scas адрес_приемника (SCAning String) — сканировать цепочку;

scasb (SCAning String Byte) — сканировать цепочку байт;

scasw (SCAning String Word) — сканировать цепочку слов;

scasd (SCAning String Double Word) — сканировать цепочку двойных слов.

Команда scas: scas адрес_приемника

Команда имеет один операнд, обозначающий местонахождение цепочки в дополнительном сегменте (адрес цепочки должен быть заранее сформирован в es:edi/di). Транслятор анализирует тип идентификатора адрес_приемника, который обозначает цепочку в сегменте данных, и формирует одну из трех машинных команд scasb, scasw или scasd. Условие поиска для каждой из этих трех команд находится в строго определенном месте. Так, если цепочка описана с помощью директивы db, то искомый элемент должен быть байтом и находиться в al, а сканирование цепочки осуществляется командой scasb; если цепочка описана с помощью директивы dw, то это — слово в ax, и поиск ведется командой scasw; если цепочка описана с помощью директивы dd, то это — двойное слово в eax, и поиск ведется командой scasd. Принцип поиска тот же, что и в команде сравнения cmps, то есть последовательное выполнение вычитания (содержимое_регистра_аккумулятора - содержимое_очередного_элемента_цепочки).

В зависимости от результатов вычитания производится установка флагов, при этом сами операнды не изменяются. Так же, как и в случае команды cmps, с командой scas удобно использовать префиксы repe/repz или repne/repnz:

o repe или repz — если нужно организовать поиск до тех пор, пока не будет выполнено одно из двух условий:

§ достигнут конец цепочки (содержимое ecx/cx равно 0);

§ в цепочке встретился элемент, отличный от элемента в регистре al/ax/eax;

o repne или repnz — если нужно организовать поиск до тех пор, пока не будет выполнено одно из двух условий:

§ достигнут конец цепочки (содержимое ecx/cx равно 0);

§ в цепочке встретился элемент, совпадающий с элементом в регистре al/ax/eax.

Таким образом, команда scas с префиксом repe/repz позволяет найти элемент цепочки, отличающийся по значению от заданного в аккумуляторе. Команда scas с префиксом repne/repnz позволяет найти элемент цепочки, совпадающий по значению с элементом в аккумуляторе.

Рассмотрим пример. В программе используется команда-примитив scas. Символ задается явно (строка 20). Префикс повторения — repne.

Пример: Поиск символа в строке командой scas<2> MASM<3> MODEL small<4> STACK 256<5>.data<6>;тексты сообщений<7> fnd db 0ah,0dh,'Символ найден! ','$'<8> nochar db 0ah,0dh,'Символ не найден.','$'<9>;строка для поиска<10> string db 'Поиск символа в этой строке.',0ah,0dh,'$'<11>.code<12> ASSUME ds:@data,es:@data<13> main:<14> mov ax,@data<15> mov ds,ax<16> mov es,ax;настройка ES на DS<17> mov ah,09h<18> lea dx,string<19> int 21h;вывод сообщения string<20> mov al,'а';символ для поиска — `а`(кириллица)<21> cld;сброс флага df<22> lea di,string;загрузка в es:di смещения строки<23> mov cx,29;для префикса repne — длина строки<24>;поиск в строке (пока искомый символ и символ в строке не совпадут)<25>;выход при первом совпадении<26> repne scas string<27> je found;если равны — переход на обработку,<28> failed:;иначе выполняем некоторые действия<29>;вывод сообщения о том, что символ не найден<30> mov ah,09h<31> lea dx,nochar<32> int 21h;вывод сообщения nochar<33> jmp exit;на выход<34> found:;совпали<35> mov ah,09h<36> lea dx,fnd<37> int 21h;вывод сообщения fnd<38>;теперь, чтобы узнать место, где совпал элемент в строке,<39>;необходимо уменьшить значение в регистре di и вставить нужный обработчик<40>; dec di<41>... вставьте обработчик<42> exit:;выход<43> mov ax,4c00h<44> int 21h<45> end main

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: