assembler. Учебник для вузов_Юров В.И_2003 -637с (862834), страница 58
Текст из файла (страница 58)
Поэтому после выхода из цикла в этих регистрах будут находиться адреса элементов, находящихся в цепочке после (!) элементов, послуживших причиной выхода из цикла. Для получения истинного адреса этихэлементов необходимо скорректировать содержимое индексных регистров, увеличив либо уменьшив значение в них на длину элемента цепочки.В качестве примера рассмотрим программу из листинга 12.2, в которой сравнивается две строки, находящиеся в одном сегменте.
Используется команда CMPS.Префикс повторения — REPE.Листинг 12.2. Сравнение двух строк командой CMPS<l>;prg_12_2.asm<2>MODELsmall256<3>STACK<4>.data0ah,0dh,'Сравнение закончено','$'<5>matchdb 00ah,0dh,'Строки не совпадают','$'<6>faileddb 0<7>stringl db '0123456789',0ah,0dh,'$';исследуемые строки<8>string2 db '9123406780','$'<9>.codees:@data;привязка DS и ES к сегменту данных<10>ASSUME ds:(i»d11<12>mov ax,@data;загрузка сегментных регистров<13>mov ds.ax<14>mov es.ax;настройка ES на DS<15>;вывод на экран исходных строк stringl и string2<16>mov ah,09h<17>lea dx,stringl<18>int 21h<19>lea dx,string2<20>int 21h<21>;сброс флага OF - сравнение в направлении возрастания адресов<22>eld<23>lea si,stringl;загрузка в si смещения stringl<24>lea di,string2;загрузка в di смещения string2<25>mov ex,10;длина строки для префикса гере<26>;сравнение строк (пока сравниваемые элементы строк равны)продолжение £9 Змс.
256258Глава 12. Цепочечные командыЛистинг 12.2 (продолжение)<27>;выход при обнаружении несовпавшего элемента<28>сус1:<29>j c x z end_hand;для последнего элемента<30>гереcmpsstringl,string2<31>je end_hand;для последнего элемента< 3 2 > ; н е совпали<33>mov ah,09h<34>lea d x , f a i l e d<35>int. 21h; вывод сообщения< 3 6 > ; т е п е р ь , чтобы обработать несовпавший элемент в строке,;необходимо уменьшить значения р е г и с т р о в si и di<37>dec si<38>dec di< 3 9 > ; с е й ч а с в d s : s i и es:di адреса несовпавших элементов< 4 0 > ; з д е с ь в с т а в и т ь код по обработке несовпавшего элемента<41>;после э т о г о продолжить поиск в с т р о к е :<42>inc si<43>inc di<44>jmp cycl<45>end_hand:<46>mov ah,09h;вывод сообщения<47>lea d x , m a t c h<48>int.
21h<49>exit:;выход<50>mov a x , 4 c 0 0 h<51>int 21h<52>end main;конец программыВ программе есть несколько требующих пояснений моментов. Это, во-первых,строки 37 и 38, в которых мы скорректировали адреса очередных элементов дляполучения адресов несовнавших элементов. Необходимо понимать, что если сравниваются цепочки с элементами слов или двойных слов, то нужно корректироватьсодержимое регистров ESI/SI и EDI/DI на 2 п. 4 байта соответственно. Во-вторых,это строки 42 п 43. Смысл их в том, что для просмотра оставшейся часта строкнеобходимо установит!) указатели на следующие элементы строк за последниминесовпавпшмн элементами. После этого можно повторить весь процесс просмотраи обработки нссовиавших элементов в оставшихся частях строк.
В-третьих, этостроки 28—31, с помощью которых учитываются особенности самих строк. Особоевнимание следует уделить обработке последних элементов строк в предположении, что они могут не совпасть. Предлагаю вам проследить за выполнением программы в отладчике наследующих наборах входных данных:stringl = '0123456789' п string2 = '0123406789';stringl = '0123456789' и string2 = '9123406780',Сравнение байтов, слов и двойных словГак же как п в группе команд пересылки цепочки, в группе команд сравнения естьотдельные команды для сравнения цепочек байтов, слов, двойных слов — CMPSB,CMPSW и CMPSD соответственно.
Для этих команд все рассуждения аналогичны тем,что были приведены при описании команд пересылки. Ассемблер преобразует команду CMPS в одну из машинных команд, CMPSB, CMPSW или CMPSD, в зависимости отразмера элементов сравниваемых цепочек.Сканирование цепочек259Сканирование цепочекКоманды, реализующие операцию-примитив сканирования цепочек, производятпоиск некоторого значения в области памяти. Логически эта область памяти рассматривается как последовательность (цепочка) элементов фиксированной длины размером 8, 16 или 32 бита. Искомое значение' предварительно должно бытьпомещено в один из регистров AL/AX/EAX.
Выбор конкретного регистра из этих трехдолжен быть согласован с размером элементов цепочки, в которой осуществляется поиск. Система команд процессора предоставляет программисту четыре команды сканирования цепочки. Выбор конкретной команды определяется размеромэлемента:Р SCAS адрес_приемника — сканировать цепочку (SCAning String);II 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.S REPE или REPZ — если нужно организовать поиск до тех пор, иока не будет выполнено одно из двух условий:О будет достигнут конец цепочки (содержимое ЕСХ/СХ равно 0);П в цепочке встретится элемент, отличный от элемента в регистре AL/AX/EAX.til REPNE или REPNZ — если нужно организовать поиск до тех пор, пока не будетвыполнено одно из двух условий:П будет достигнут конец цепочки (содержимое ЕСХ/СХ равно 0);П в цепочке встретится элемент, совпадающий с элементом в регистре AL/AX/EAX.260Глава 12.
Цепочечные командыТаким образом, команда SCAS с префиксом REPE/REPZ позволяет найти элементцепочки, отличающийся по значению от заданного в аккумуляторе. Команда SCASс префиксом REPNE/REPNZ позволяет найти элемент цепочки, совпадающий по значению с элементом в аккумуляторе. В качестве примера рассмотрим листинг 12.3,в котором реализован поиск символа в строке. В программе используется команда-примитив SCAS. Символ задается явно (строка 20). Префикс повторения — REPNE.Листинг 12.3. Поиск символа в строке командой SCAS;prg_12_3.asmMASMMODEL smallSTACK256.data; тексты сообщенийfnd db 0ah,0dh,'Символ найден! ","$'nochar db Oah,0dh,'Символ не найден.','$';строка для поискаstring db "Поиск символа в этой строке.",Oah,0dh,'$'.codeASSUME ds:@data,es:@datamain:mov ax,@datamov ds,axmov es.ax;настройка ES на DSmov ah,09hlea dx,stringint 21h;вывод сообщения stringmov al.'a';символ для поиска - "а"(кириллица)eld;сброс флага dflea di,string ;загрузка в es:di смещения строкиmov ex,28;для префикса repne - длина строки;поиск в строке (пока искомый символ и символ в строке не совпадут);выход при первом совпаденииrepne seas stringje found;если равны - переход на обработку,failed:;иначе - выполняем некоторые действия;вывод сообщения о том, что символ не найденmov ah,Q9hlea dx,nocharint 21h;вывод сообщения nocharjmp exit;на выходfound:;совпалиmov ah,Q9hlea dx.fndint 21h;вывод сообщения fnd;теперь, чтобы узнать место, где совпал элемент в строке,;необходимо уменьшить значение в регистре di и вставить нужный обработчик;dec di;...
вставьте обработчикexit:;выходmov ax,4c00hint 21hend mainСканирование строки байтов, слов, двойных словСистема команд процессора, так же как в случае операций-примитивов пересылкии сравнения, предоставляет команды сканирования, явно указывающие размерэлемента цепочки — SCASB, SCASW или SCASD. Помните, что даже если вы этого неделаете, то ассемблер все равно преобразует команду SCAS в одну из этих трех машинных команд.Загрузка элемента цепочки в аккумулятор261Загрузка элемента цепочки в аккумуляторОперация-примитив загрузки элемента цепочки в аккумулятор позволяет извлечьэлемент цепочки и поместить его в регистр-аккумулятор AL, АХ или ЕАХ.
Эту операцию удобно использовать вместе с поиском (сканированием) с тем, чтобы, найдянужный элемент, извлечь его (например, для изменения). Возможный размер извлекаемого элемента определяется применяемой командой. Программист можетиспользовать четыре команды загрузки элемента цепочки в аккумулятор, работающие с элементами разного размера:т LODS адрес_источника — загрузить элемент из цепочки (LOaD String) в регистраккумулятор AL/AX/EAX;И LODSB — загрузить байт из цепочки (LOaD String Byte) в регистр AL;* LODSW — загрузить слово из цепочки (LOaD String Word) в регистр АХ;II LODSD — загрузить двойное слово (LOaD String Double Word) из цепочки в регистр ЕАХ.Рассмотрим работу этих команд на примере команды LODS.Команда LODSСинтаксис команды LODS:lods адрес_источникаКоманда имеет один операнд, обозначающий строку в основном сегменте данных.