- •Глава 12
- •Пересылка цепочек
- •Команда movs
- •Пересылка байтов, слов и двойных слов
- •Сравнение цепочек
- •Команда cmps
- •Сравнение байтов, слов и двойных слов
- •Сканирование цепочек
- •Команда scas
- •Сканирование строки байтов, слов, двойных слов
- •Загрузка элемента цепочки в аккумулятор
- •Команда lods
- •Загрузка в регистр al/ax/eax байтов, слов, двойных слов
- •Перенос элемента из аккумулятора в цепочку
- •Команда stos
- •Сохранение в цепочке байта, слова, двойногослова из регистра al/ax/eax
- •Работа с портами ввода-вывода
- •Ввод элемента цепочки из порта ввода-вывода
- •Вывод элемента цепочки в порт ввода-вывода
Сканирование строки байтов, слов, двойных слов
Система команд процессора, так же как в случае операций-примитивов пересылки и сравнения, предоставляет команды сканирования, явно указывающие размер элемента цепочки — SCASB, SCASW или SCASD. Помните, что даже если вы этого не делаете, то ассемблер все равно преобразует команду SCAS в одну из этих трех машинных команд.
Загрузка элемента цепочки в аккумулятор
Операция-примитив загрузки элемента цепочки в аккумулятор позволяет извлечь элемент цепочки и поместить его в регистр-аккумулятор AL, АХ или ЕАХ. Эту операцию удобно использовать вместе с поиском (сканированием) с тем, чтобы, найдя нужный элемент, извлечь его (например, для изменения). Возможный размер извлекаемого элемента определяется применяемой командой. Программист может использовать четыре команды загрузки элемента цепочки в аккумулятор, работающие с элементами разного размера:
LODS адрес_источника — загрузить элемент из цепочки (LOaD String) в регистр аккумулятор AL/AX/EAX;
LODSB — загрузить байт из цепочки (LOaD String Byte) в регистр AL;
LODSW — загрузить слово из цепочки (LOaD String Word) в регистр АХ;
LODSD — загрузить двойное слово (LOaD String Double Word) из цепочки в регистр ЕАХ.
Рассмотрим работу этих команд на примере команды LODS.
Команда lods
Синтаксис команды LODS:
lods адрес_источника
Команда имеет один операнд, обозначающий строку в основном сегменте данных. Работа команды заключается в том, чтобы извлечь элемент из цепочки по адресу, соответствующему содержимому пары регистров 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.asm
MASM
MODEL small
STACK 256
.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 -, л.
main:
mov ax ,@data ; загрузка сегментных регистров
mov ds.ax
mov es.ax
mov ah,09h
lea dx, stringl
int 21h ;вывод stringl
lea dx,string2
i n t 21 h;вывод string2
cld
lea di , string1 ;загрузка в es:di смещения строки stringl
lea si . string2 ;загрузка в els: si смещения строки string2
movrx,29 ;для префикса гере -длина строки
;поиск в строке (пока нужный символ и символ
;в строке не равны)
;выход при первом не совпавшем
repe cmps string1, string2
jcxzeql;если равны - переход на eql
jmpno_eq;если не равны - переход на no_eq
eql. :выводим сообщение о совпадении строк
mov ah,09h
lea dx,mes_eq
int 21h
jmp exit
no_eq: ;обработка несовпадения элементов
mov ah , 09h
lea dx.fnd
int 21h ;вывод сообщения fnd
;теперь, чтобы извлечь несовпавший элемент из строки
;в регистр-аккумулятор,
;уменьшаем значение регистра si и тем самым перемещаемся
;к действительной позиции элемента в строке
dec si ;команда lods использует ds:si-адресацию
;теперь ds:si указывает на позицию в string2
lods string2
;нетрудно догадаться
e x i t :
mov ax,4c00h
int 21h
end main
