22. Выполнение команд с префиксами. Направление обработки цепочек.

Для организации циклической обработки цепочек элементов используются префиксы повторения:
REP цепочечная_команда
Команда повторяется до тех пор, пока содержимое сх не равно нулю.
REPE/REPZ цепочечная_команда
Префиксы являются абсолютными синонимами. Команда повторяется до тех пор, пока содержимое сх не равно нулю и zf =1.
REPNE/REPNZ цепочечная_команда
Префиксы являются абсолютными синонимами. Команда повторяется до тех пор, пока содержимое сх не равно нулю и zf =0.


Условие выхода для префиксов повторения
Префикс Условие
REP cx = 0
.REPE/REPZ cx = 0 OR zf = 0
REPNE/REPNZ .cx = 0 OR zf = 1

Порядок выполнения команд с префиксами:
1) выполняется команда, перед которой стоит префикс
2) содержимое сх уменьшается на единицу
3) если условие выхода выполняется — управление передается на следующую после префиксной команду иначе — шаг 1



Еще один важный вопрос — направление обработки цепочки.
Модификация регистров, адресующих операнды, в цепочечных командах выполняется автоматически, тем самым обеспечивается продвижение по цепочке. Количество байтов, на которые это изменение осуществляется, определяется кодом команды. А вот знак этой модификации определяется значением флага направления OF (Direction Flag) в регистре EFLAGS/FLAGS:
• если DF = 0, то значения индексных регистров ESI/SI и EDI/DI будут увеличиваться (операция инкремента) цепочечными командами, то есть обработка будет осуществляться в направлении возрастания адресов;
• если DF = 1, то значения индексных регистров ESI/SI и EDI/DI будут уменьшаться (операция декремента) цепочечными.командами, то есть обработка будет идти в направлении убывания адресов.

Состоянием флага DF можно управлять с помощью двух команд, не имеющих операндов:
CLD (Clear Direction Flag) — очистить флаг направления (команда сбрасывает флаг направления DF в 0);
STD (Set Direction Flag) — установить флаг направления (команда устанавливает флаг направления DF в 1).

Пример: копирование строки
.data                                  ;сегмент даты
source_str db “string_to_copy”         ; строчка, которую будем копировать
len_source dw $ - source_str           ; длину строчки можно определить таким образом: доллар – это текущее     смещение, если от него отнять смещение предыдущего поля – получаем его длину
destination_str db len_source DUP(‘*’) ; сюда будем копировать
…
.code
Cld                                    ; сбрасываем df – обрабатываем в порядке увеличение индексов
Lea si, source_str                     ; подготовка адресных регистров
Lea di, destination_str
Mov cx, len_str                        ;загрузка количества итераций в регистр-счетчик
Rep movsb                              ;копирование
…
17.07.2015