Добавил:
vanya.tagaschev@ya.ru Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
4
Добавлен:
21.03.2021
Размер:
22.19 Кб
Скачать

2. Повторение строковой инструкции

Для повторения строковой инструкции необходимое количество раз существует префикс REP (от английского REPEAT - повтор). Префикс инструкции изменяет работу последующей инструкции. Префикс REP делает следующее: он указывает, что последующую инструкцию нужно повторно выполнять до тех пор, пока содержимое регистра СХ (регистр – счетчик) не станет равным 0. (Если регистр СХ равен 0 в начале выполнения инструкции, то инструкция выполняется 0 раз, другими словами, никаких действий не производится. Этим команда REP отличается от команды организации цикла LOOP, которая при нулевом значении CX повторится 65535 раз, т.к. сначала происходит уменьшение, затем проверка.)

Префикс REP вызывает повторение только строковой инструкции.

Инструкция типа:

rep mov ax,[bx]

не имеет смысла. В этом случае префикс rep игнорируется и выполняется инструкция:

mov ax,[bx]

А инструкция

rep STOSB

выполнит запись из регистра AL в ячейки памяти, начиная с ячейки ES:DI, до адреса ES:DI + CX.

3. Поиск данных с помощью строковой инструкции

Инструкция SCAS

Инструкция SCAS используется для просмотра памяти и поиска совпадения или несовпадения с конкретным значением размером в байт или слово. Как и все строковые инструкции, инструкция SCAS имеет две формы - SCASB и SCASW.

Инструкция SCASB сравнивает содержимое регистра AL с байтовым значением по адресу ES:DI, устанавливая при этом флаги, отражающие результат сравнения (как при выполнении инструкции СМР). Как и при выполнении инструкции STOSB, при выполнении инструкции SCASB увеличивается или уменьшается значение регистра DI.

Строковые инструкции никогда не устанавливают флаги таким образом, чтобы они отражали изменения значений регистров SI, DI и/или СХ. Инструкции STOS и MOVS вообще не изменяют никаких флагов, а инструкции SCAS и CMPS изменяют флаги только в соответствии с результатом выполняемого ими сравнения.

Префикс rep распространяется так же и на команды поиска. Однако может оказаться желательным прекратить выполнение цикла в случае совпадения или несовпадения. Для этого существует две формы префикса REP, которые можно использовать с инструкцией SCAS (и с CMPS) - repE и repNE.

Префикс REPE (который также называется префиксом REPZ) указывает процессору, что инструкцию SCAS (или CMPS) нужно повторять до тех пор, пока регистр СХ не станет равным нулю, или пока не произойдет несовпадение. Префикс repE можно рассматривать, как префикс, означающий "повторять, пока равно". Аналогично, префикс REPNE (KEPNZ) указывает процессору, что инструкцию SCAS (CMPS) нужно повторять, пока СХ не станет равным нулю или пока не произойдет совпадения. Префикс KEPNE можно рассматривать, как префикс "повторять, пока не равно".

Как и все строковые инструкции, инструкция SCAS увеличивает регистр-указатель DI, если флаг направления равен 0 (очищен с помощью инструкции CLD), и увеличивает DI, если флаг направления равен 1 (установлен с помощью инструкции STD).

Инструкция SCASW - это форма инструкции SCASB для работы со словом. Она сравнивает содержимое регистра АХ с содержимым памяти по адресу ES:DI и увеличивает или уменьшает значение регистра DI в конце каждого выполнения на 2, а не на 1.

Инструкция CMPS

Инструкция CMPS позволяет выполнять сравнение двух байт или слов. При одном выполнении инструкции CMPS сравниваются две ячейки памяти, а затем увеличиваются регистры SI и DI. Инструкцию CMPS можно рассматривать, как аналог инструкции MOVS, который вместо копирования одной ячейки памяти в другую сравнивает две ячейки памяти.

Инструкция CMPSB сравнивает байт по адресу DS:SI с байтом по адресу ES:DI, устанавливая соответствующим образом флаги и увеличивая или уменьшая регистры SI и DI (в зависимости от флага направления). Регистр АL при этом не изменяется.

Инструкция CMPSW аналогична инструкции CMPSB, отличие состоит в том, что производится сравнение слов.

ЗАДАНИЕ №1

.data

L dd n/2-1 ;левая граница неотсортированного массива

R dd n-1 ;правая граница неотсортированного массива

.code

;массив преобразуется в отображение пирамиды - вызвать процедуру

;down_heap n/2 раз для преобразования массива в пирамиду

b0: call down_heap

dec L ;while ( L > 0 ) L--;

jnz short b0

;собственно пирамидальная сортировка

dec L ;L=0

dec R ;R=n-2

b1: mov edx,R ;отправляем значение максимального

mov eax,array ;элемента в конец массива

xchg eax,array[edx*4+4] ; array[0] <--> array[R];

mov array,eax

call down_heap ;восстанавливаем пирамиду - на ее

;вершине появляется новое максимальное значение

dec R ;уменьшаем индекс последнего элемента

jnz short b1 ;while ( R > 0 ) R--;

b2: ...

;-----------------------------------------------------

down_heap proc; процедура вставки элемента на свое место в пирамиду

mov eax,L

mov ebx,eax ;i = L;

shl eax,1 ;j = 2*L;

mov esi,array[eax*2] ;item = array[L];

cmp eax,R ;if( j<R && array[j] < array[j+1]) j++;

jnb short a0

mov edx,array[eax*4]

cmp edx,array[eax*4+4] ;array[j] < array[j+1] ?

jnb short a0

; условие j<R && array[j]<array[j+1] выполнилось

inc eax ;j++

a0: cmp eax,R ;while( j£R && item < array[j])

ja short a1

mov edi,array[eax*4]

cmp esi,edi ;item < array[j] ?

jnb short a1

; условие j<=R && item < array[j] выполнилось

mov array[ebx*4],edi ;array[i] = array[j];

mov ebx,eax ;i = j;

shl eax,1 ;j = 2*j;

cmp eax,R

jnb short a0;if( j<R && array[j] < array[j+1]) j++;

mov edx,array[eax*4]

cmp edx,array[eax*4+4]

jnb short a0

; условие j<R && array[j] < array[j+1] выполнилось

inc eax ;j++

jmp short a0

a1: mov array[ebx*4],esi ;array[i] = item;

retn

down_heap endp

ЗАДАНИЕ №2

masm

model small

.data

var1 db 12

.stack 256h

.code

main proc

mov ah,var1

mov ds:[0000h],ah

mov al,ds:[0000h]

mov ax,4c00h

int 21h

main endp

end main

Вывод: Получено освоение способов работы с памятью посредством строковых инструкций.

Соседние файлы в папке Тамьяров А. В.