Использование команд для работы с блоками
Команды позволяют обрабатывать массив чисел длиной 1, 2, 4 байтов, начиная с начала или конца массива. При этом автоматически изменяется адрес элемента массива на длину элемента массива. Для массива можно выполнить следующие операции:
копирование массива в другой массив:
сравнение двух массивов;
заполнение массива заданным значением или последовательным чтением элементов массива;
поиск заданного элемента массива.
Для определения направления поиска устанавливается флаг d регистра флагов (бит № 10).
Адрес исходного массива задается в регистре ESI, а результирующего - в регистре EDI.
Количество элементов массива задается в регистре ECX.
Команды :
MOVS{B|W|D} - do{*(edi++) = *(esi++) while (ecx--);}
LODS{B|W|D} {AL|AX|EAX} = *(esi++)
STOS{B|W|D} *(edi++) = {AL|AX|EAX}
CMPS{B|W|D} сравнение *(esi++) и *(edi++)
SCAS{B|W|D} do{ if {AL|AX|EAX} = (!=) ) *(edi++) break; while (ecx--);
В таблице 7.1 представлена сводная таблица команд для работы с блоками
Таблица 7.1. Сводная таблица команд для работы с блоками
Код | Выполняемые действия | Подготовка команды | Используемый префикс | ||||
MOVS | dest = src | cld (std);
esi = &src[10] edi = & dest ecx = number | REP | ||||
LODS | {al, ax, eax} = *esi++ | cld (std);
esi = &src | Префикс не используется | ||||
STOS | *edi++ = {al, ax, eax} | cld (std);
edi = &dest ecx = number | REP | ||||
CMPS | *src ++
<>*dest++ | cld (std);
esi = &src7 edi = & dest ecx = number | REPE, REPNE | ||||
SCAS | {al, ax, eax} <>
*dest++ | EAX - что ищем,
edi = & dest (где ищем) ecx = number | REPE, REPNE |
Примеры использования команд
Скопировать область памяти заданной длины в другую область памяти, если адрес начала первой области f1, ее размер len байт, адрес начала второй области f2. Пусть len кратно 4.
В этой программе сначала определяется направление копирования. Если области памяти для исходного и результирующего массивов пересекаются, при этом адрес начала результирующего массива больше, чем адрес исходного, необходимо копировать, начиная с конца массива, в противном случае – с начала.
Е
Movаааа esi, [f1]
Movаааа edi, [f2]
Movаааа ecx, [len]
Shrаааааа ecx, 2
Jecxzааа m1
cld
cmpаааа esi, edi
jaаааааааа short m2
jeаааааааа break
movаааа esi, eax
decаааааа esi
addааааа edi, [len]
decаааааа edi
std
m2:
repаааааа movsd
break:
cld
¦ЁшьхЁ 2. T чрфрээющ ёЄЁюъх ьрыхэ№ъшх ырЄшэёъшх сєътv чрьхэшЄ№ сюы№°шьш.
Str1ааааа dbааааааа СThis is stringТ,0
Е
cld
movаааа esi, offset str1
movаааа edi, offset str1
for1:
lodsb
testаааааа al, al
jeаааааааа short break
cmpаааа al, СaТ
jbаааааааа notl
cmpаааа al, СzТ
jaаааааааа notl
addааааа al, СAТ Ц СaТ
notl:
stosb
jmp for1
break:
cld
¦ЁшьхЁ 3. TюёЄртшЄ№ яЁюуЁрььє фы ёЁртэхэш фтєї фышээvї ўшёхы юфшэръютющ фышэv. ¦ЁюуЁрььр фюыцэр ЇюЁьшЁютрЄ№ Ёхчєы№ЄрЄ >0, хёыш яхЁтюх ўшёыю сюы№°х тЄюЁюую, Ёртэю 0, хёыш ўшёыр Ёртэv ш <0, хёыш яхЁтюх ўшёыю ьхэ№°х тЄюЁюую. ¦єёЄ№ ўшёыю ёюёЄюшЄ шч n 32-сшЄэvї лЎшЇЁ¬ ш чряшёvтрхЄё , эрўшэр ё ьырф°шї ЎшЇЁ.
Xааааааааа ddааааааа Е, Е., Е.
Yааааааааа ddааааааа Е, Е, Е
Nаааааааа ddааааааа (Y Ц X)/4
Resааааа ddааааааа ?
Е
subаааааа eax, eax
movаааа ecx, [N]
leaаааааа esi , [X+ecx*4-4]
leaаааааа edi , [Y+ecx*4-4]
std
repeаааа cmpsd
jecxzааа m1
jbаааааааа letter
movаааа eax, 1
jmpааааа short m1
letter: movаааааа eax, -1
m1:
cld
ааааааааа
¦ЁшьхЁ 4.
T чрфрээюь ьрёёштх ўшёхы тёх эєыхтvх чэрўхэш чрьхэшЄ№ Ц1
While (){
аа If (хёЄ№ эєыхтюх чэрўхэшх)
аа ааа¦рьхэшЄ№;
аа Else
ааааа Break;
}
movаааа ecx, [n]
cld
subаааааа eax, eax
movаааа edi, offset x
for1:
repneаа scasd
jecxzааа break
movаааа [dword ptr edi-4], -1
jmpааааа for1