assembler. Учебник для вузов_Юров В.И_2003 -637с (862834), страница 59
Текст из файла (страница 59)
Работа команды заключается в том, чтобы извлечь элемент из цепочки поадресу, соответствующему содержимому пары регистров DS: ESI/SI, и поместить егов регистр EAX/AX/AL. При этом содержимое ESI/SI подвергается инкременту илидекременту (в зависимости от состояния флага DF) на величину, равную размеруэлемента. Эту команду удобно использовать после команды SCAS, локализующейместоположение искомого элемента в цепочке.
Префикс повторения в этой командеможет и не понадобиться — все зависит от логики программы.В качестве примера рассмотрим листинг 12.4, в котором командой CMPS сравниваются две цепочки байтов в памяти (stringl и string2) и первый не совпавшийбайт из stringZ помещается в регистр AL. Для загрузки этого байта в регистр-аккумулятор AL используется команда LODS. Префикса повторения в команде LODS нет,так как он попросту не нужен.Листинг 12.4. Использование команды LODS для загрузки байта в регистр AL:prg_ll_4.asmMASMMODELsmallSTACK256.data;строки для сравненияstringl db "Поиск символа в этой строке.",0ah,0dh,'$'string2 db "Поиск символа не в этой строке.",0ah,0dh,'$'mes_eq db "Строки совпадают.",0ah,0dh,'$'fnd db "Несовпавший элемент в регистре al",0ah,0dh,'$'.code;привязка ds и es к сегменту данныхassume ds:@data,es:@data-,л.продолжение &262Глава 12.
Цепочечные командыЛистинг 12,4 (продолжение)та i n.movmovmovmovleaintleai nteldlealeamovax ,(E>data ; загрузка сегментных регистровds.axes.ax.настройкаah,09hd x , s t r i ngl21h;вывод string!dx,string221 hвывод string2сброс флага dfз а г р у з к а в e s : d i смещения строки stringla i , s 11" 1n % 1si . s t r i n g 2з а г р у з к а в els: si смещения строки string2rx,29для префикса гере -- длина строкипоиск в строке ''пока нужный символ и символв строке не равны);выходпри первом не совпавшемrepecrops :,t.ringl string^jcxz eqlесли равны - переход на eqlесли не равны - переход на no_eqjmp no_eqвыводим сообщение о совпадении строкeql.
:mov ah,99tlea dx,mes_eqвывод сообщения mes_eqint 21hна выходjmp e x i tno _eq:обработка несовпадения элементовmov ah , 09hlea dx.fndi n t 21hвывод сообщения fnd;теперь, чтобы извлечь несовпавший элемент из строки;в р е г и с т р - а к к у м у л я т о р ,;уменьшаем значение регистра si и тем самым перемещаемся;к действительной позиции элемента в строкеdec si;команда Tods использует ds:si-адресацию;теперь ds:si указывает на позицию в s t r i n g ?загрузим элемент из строки в ALlods string2;нетрудно догадаться что в нашем примере эго символ - "н"exit:выходmov ax,4c00hint 21hend m a i nЗагрузка в регистр AL/AX/EAX байтов, слов,двойных словКоманды загрузки байта в регистр AL (LODSB), слона — в регистр АХ (LODSW), двойного слова в регистр ЕАХ (LODSD) аналогичны другим цепочечным командам.
Ониявляются вариантами команды LODS. Каждая из этих команд работает с цепочкамииз элементов определенного размера. Предварительно вы должны загрузить значение длины цепочки л ее адрес в регистры ЕСХ/СХ и DS;ESI/SLПеренос элемента из аккумулятораОперацпя-пртнгпш переноса элемента из аккумулятора в цепочку'позволяет произвести дсй,:твие, обратное действию команды LODS, то есть сохранить значение изрегистра-аккумулятора в элементе цепочки.
Эту операцию удобно использоватьПеренос элемента из аккумулятора в цепочку263вместе с операциями поиска (сканирования) SCANS и загрузки LODS с тем, чтобы,найдя нужный элемент, извлечь его в регистр и записать на его место новое значение. Команды, поддерживающие эту операцию-примитив, могут работать с: элементами размером 8, 16 или 32 бита. Т ASM предоставляет программисту четырекоманды сохранения элемента цепочки из регистра-аккумулятора, работающиес элементами разного размера:STOS адрес_приемника — сохранить в цепочке элемент (STOre String) из регистра-аккумулятора AL/AX/EAX;STOSB — сохранить в цепочке байт (STOre String Byte) из регистра AL;STOSW — сохранить в цепочке слово (STOre String Word) из регистра АХ;STOSD — сохранить в цепочке двойное слово (STOre Siring Double Word) из регистра ЕАХ.Команда STOSСинтаксис команды STOS:stos адрес_приемникаКоманда имеет один операнд адрес_приемника, адресующий цепочку в дополнительном сегменте данных.
Команда пересылает элемент из аккумулятора (регистра EAX/AX/AL) в элемент цепочки по адресу, соответствующему содержимому парырегистров ES:EDI/DI. При этом содержимое EDI/DI подвергается инкременту илидекременту (в зависимости от состояния флага DF) па величину, равную размеруэлемента цепочки.Префикс повторения в этой команде может и не понадобиться — все зависит отлогики программы. Например, если использовать префикс повторения REP, то можно применить команду для инициализации области памяти некоторым фиксированным значением.В качестве примера рассмотрим листинг 12.5, в котором производится заменав строке всех символов «а» символами, вводимыми^ клавиатуры.Листинг 12.5.
Замена командой STOS символа в строке символом, вводимымс клавиатуры;prg_12_5.asmHASHMODELsmallSTACK256.data;сообщенияfnd db Oah,0dh,'Символ найден','$'nochar db 0ah ,Sdh,'Символ не найден.'.'$'mesldb Oah,0dh,'Исходная строка:','$'string db "Поиск символа в этой строке.",Qah,0dh,'$' ;строка для поиска 1rnes2db 0ah,0dh, ' Введите символ, на который следует заменить н а й д е н н ы йdb 0ah,0dh,'$'mes3db Oah ,0dh,'Новая строка: ","$'.codeпривязка ds и esassume ds:@da£a,es:@dataк сегменту данныхточка входа в программуmain:загрузка сегментных регистровmov ax.gdata264Глава 12. Цепочечные командыЛистинг 12.5 (продолжение)mov d s .
a xmov es.ax;настройка es на dsmov ah,09hlea dx.meslint 21h;вывод сообщения mesllea dx,stringint 21h;вывод stringeld;сброс флага dflea di,string;загрузка в di смещения stringmov ex,28;для префикса repne - длина строкипоиск в строке string до тех пор, покасимвол в al и очередной символ в строкене равны: выход — при первом совпаденииcycl:mov al.'a';символ для поиска - "а"(кириллица)repne seas stringje found;если элемент найден, то переход на foundfailed:;иначе, если не найден, то вывод сообщения nocharmov ah,09hlea dx,nocharint 21hjmp exit;переход на выходfound:mov ah,09hlea dx.fndint 21h;вывод сообщения об обнаружении символакорректируем di для получения значениядействительной позиции совпавшего элемента;в строке и регистре aldec dinew_char:;блок замены символаmov ah,09hlea dx,mes2int 21h;вывод сообщения mes2;ввод символа с клавиатурыmov ah,01hint 21h;в al - введенный символstosstring ;сохраним введенный символ; (из al) в строке;string в позиции старого символаmov ah,09hlea dx,mes3int 21h;вывод сообщения mes3lea dx,stringint 21h;вывод сообщения string;переход на поиск следующего символа "а" в строкеinc diуказатель в строке string на символ,;следующий после совпавшего,jmp cycl;на продолжение просмотра stringexit:;выходmov ax,4c00hint 21hend m a i n;конец программыСохранение в цепочке байта, слова, двойногослова из регистра AL/AX/EAXКоманды STOSB, STOSW и STOSD, аналогично другим цепочечным операциям, являются вариантами команды STOS.
Каждая из этих команд работает с цепочками изэлементов определенного размера. Предварительно необходимо загрузить значение длины цепочки и ее адрес в регистры ЕСХ/СХ и ES:EDI/DI.Работа с портами ввода-вывода265Работа с портами ввода-выводаОписанные далее две команды появились впервые в системе команд процессораi386.
Они позволяют организовать эффективную передачу данных между портамиввода-вывода и цепочками в памяти. Следует отметить, что эти две команды позволяют достичь более высокой скорости передачи данных по сравнению с тойскоростью, которую может обеспечить контроллер DMA (Direct Memory Access —прямой доступ к памяти).Ввод элемента цепочки из порта ввода-выводаОперация ввода элемента цепочки из порта ввода-вывода реализуется командойINS (Input String), имеющей следующий формат:ins адрес_приемника,номер_портаЭта команда вводит элемент из порта, номер которого находится в регистре DX,в элемент цепочки, адрес памяти которого определяется операндом адрес_приемника. Несмотря на то, что цепочка, в которую вводится элемент, адресуется указанием этого операнда, ее адрес должен быть явно сформирован в паре регистровES:EDI/DI.
Размер элементов цепочки должен быть согласован с размером порта —он определяется директивой резервирования памяти, с помощью которой выделяется память для размещения элементов цепочки. После пересылки команда INSпроизводит коррекцию содержимого регистра EDI/DI на величину, равную размеру элемента, участвовавшего в операции пересылки.
Как обычно, при работе цепочечных команд учитывается состояние флага DF.Подобно командам, реализующим рассмотренные ранее цепочечные операциипримитивы, транслятор преобразует команду INS в одну из трех машинных командбез операндов, работающих с цепочками элементов определенного размера:INSB (INput String Byte) — ввести из порта цепочку байтов;INSW (INput String Word) — ввести из порта цепочку слов;INSD (INput String Double Word) — ввести из порта цепочку двойных слов.К примеру, введем из порта SOOOh 10 байтов в область памяти pole:.datapole.codedb10 dup (" ")push dspop es ;настройка es на dsmov dx,5000hlea di.polemov ex,10rep insbВывод элемента цепочки в порт ввода-выводаОперация вывода элемента цепочки в порт ввода-вывода реализуется командойOUTS (Output String), имеющей следующий формат:outs номер_порта,адрес_источникаЭта команда выводит элемент цепочки в порт, номер которого находится в регистре DX.
Адрес элемента цепочки определяется операндом адрес_источника.266Глава 12. Цепочечные командыНесмотря на то, что цепочка, из которой выводится элемент, адресуется указанием .ггого операнда, значение адреса должно быть явно сформировано в паре регистров DS:t'SI/SI. Размер структурных элементов цепочки должен быть согласованс размером порта — он определяется директивой резервирования памяти, с помощью которой выделяется память для размещения элементов цепочки. После пересылки команда OUTS производит коррекцию содержимого регистра ESI/SI на величину, равную размеру элемента цепочки, участвовавшего в операции пересылки.При этом, как обычно, учитывается состояние флага DF.Подобно команде INS транслятор преобразует команду OUTS в одну из трех машинных команд без операндов, работающих с цепочками элементов определенного размера:* OUTSB (OUTput String Byte) - вывести цепочку байтов в порт ввода-вывода;>? OUTSW (OUTtput String Word) — вывести цепочку слов в порт ввода-вывода;;s OUTSD (OUTput String Double Word) — вывести цепочку двойных слов в портввода-вывода.В качестве примера рассмотрим фрагмент программы, которая выводит последовательность символов в порт ввода-вывода с номером 378 (Iptl), соответствующий принтеру:.