Rep/repe/repz/repne/repnz
(REPeat string operation)
Повторить цепочечную операцию
Схема команды: | rep repe repz repne repnz |
Назначение: указание условного и безусловного повторения следующей за данной командой цепочечной операции.
Синтаксис
Алгоритм работы:
Алгоритм работы зависит от конкретного префикса. Префиксы rep, repe и repz на самом деле имеют одинаковый код операции, их действия зависят от той цепочечной команды, которую они предваряют:
- rep используется перед следующими цепочечными командами и их краткими эквивалентами: movs, stos, ins, outs. Действия rep:
- анализ содержимого cx:
- если cx<>0, то выполнить цепочечную команду, следующую за данным префиксом и перейти к шагу 2;
- если cx=0, то передать управление команде, следующей за данной цепочечной командой (выйти из цикла по rep);
- уменьшить значение cx=cx–1 и вернуться к шагу 1;
- repe и repz используются перед следующими цепочечными командами и их краткими эквивалентами: cmps, scas. Действия repe и repz:
- анализ содержимого cx и флага zf:
- если cx<>0 или zf<>0, то выполнить цепочечную команду, следующую за данным префиксом, и перейти к шагу 2;
- если cx=0 или zf=0, то передать управление команде, следующей за данной цепочечной командой (выйти из цикла по rep);
- уменьшить значение cx=cx-1 и вернуться к шагу 1;
- repne и repnz также имеют один код операции и имеют смысл при использовании перед следующими цепочечными командами и их краткими эквивалентами: cmps, scas. Действия repne и repnz:
- анализ содержимого cx и флага zf:
- если cx<>0 или zf=0, то выполнить цепочечную команду, следующую за данным префиксом и перейти к шагу 2;
- если cx=0 или zf<>0, то передать управление команде, следующей за данной цепочечной командой (выйти из цикла по rep);
- уменьшить значение cx=cx–1 и вернуться к шагу 1.
Состояние флагов после выполнения команды:
ZF |
r |
Применение:
Команды rep, repe, repz, repne и repnz в силу специфики своей работы называются префиксами. Они имеют смысл только при использовании цепочечных операций, заставляя их циклически выполняться и тем самым без организации внешнего цикла обрабатывать последовательности элементов фиксированной длины. Большинство применяемых префиксов являются условными, то есть они прекращают работу цепочечной команды при выполнении определенных условий.
См. также: урок 11 и команды cmps/cmpsb/cmpsw/cmpsd, ins/insb/insw/insd, outs, movs/movsb/movsw/movsd, scas/scasb/scasw/scasd, stos/stosb
/stosw/stosd
RET/RETF
(RETurn/RETurn Far from procedure)
Возврат ближний (дальний) из процедуры
Схема команды: | ret ret число |
Назначение: возврат управления из процедуры вызывающей программе.
Синтаксис
Алгоритм работы:
Работа команды зависит от типа процедуры:
- для процедур ближнего типа — восстановить из стека содержимое eip/ip;
- для процедур дальнего типа — последовательно восстановить из стека содержимое eip/ip и сегментного регистра cs.
- если команда ret имеет операнд, то увеличить содержимое esp/sp на величину операнда число; при этом учитывается атрибут режима адресации — use16 или use32:
- если use16, то sp=(sp+число), то есть указатель стека сдвигается на число байт, равное значению число;
- если use32, то sp=(sp+2*число), то есть указатель стека сдвигается на число слов, равное значению число.
Состояние флагов после выполнения команды:
выполнение команды не влияет на флаги |
Применение:
Команду ret необходимо применять для возврата управления вызывающей программе из процедуры, управление которой было передано по команде call. На самом деле микропроцессор имеет три варианта команды возврата ret - это ret, ее синоним retn, а также команда retf. Они отличаются типами процедур, в которых используются. Команды ret и retn служат для возврата из процедур ближнего типа. Команда retf — команда возврата для процедур дальнего типа. Какая конкретно команда будет использоваться, определяется компилятором; программисту лучше использовать команду ret и доверить транслятору самому сгенерировать ее ближний или дальний вариант. Количество команд ret в процедуре должно соответствовать количеству точек выхода из нее.
Некоторые языки высокого уровня, к примеру Pascal, требуют, чтобы вызываемая процедура очищала стек от переданных ей параметров. Для этого команда ret содержит необязательный параметр число, который, в зависимости от установленного атрибута размера адреса, означает количество байт или слов, удаляемых из стека по окончании работы процедуры.
my_proc proc... ret 6 endp |
См. также: уроки 10, 14 и команду call
ROL
(Rotate operand Left)
Циклический сдвиг операнда влево
Схема команды: | rol операнд,количество_сдвигов |
Назначение: операция циклического сдвига операнда влево.
Синтаксис
Алгоритм работы:
- сдвиг всех битов операнда влево на один разряд, при этом старший бит операнда вдвигается в операнд справа и становится значением младшего бита операнда;
- одновременно выдвигаемый бит становится значением флага переноса cf;
- указанные выше два действия повторяются количество раз, равное значению второго операнда.
Состояние флагов после выполнения команды:
OF | CF |
?r | r |
Применение:
Команда rol используется для циклического сдвига разрядов операнда влево. Отличие этого сдвига от rcl в том, что очередной сдвигаемый бит одновременно вдвигается в операнд справа и становится значением флага cf. Так же, как и для других сдвигов, значение второго операнда (счетчика сдвига) ограничено диапазоном 0...31. Это объясняется тем, что микропроцессор использует только пять младших разрядов операнда количество_разрядов. Аналогично другим командам сдвига сохраняется эффект, связанный с поведением флага of, значение которого имеет смысл только в операциях сдвига на один разряд:
- если of=1, то текущее значение флага cf и выдвигаемого слева бита операнда различны;
- если of=0, то текущее значение флага cf и выдвигаемого слева бита операнда совпадают.
Этот эффект, как вы помните, обусловлен тем, что флаг of устанавливается в единицу всякий раз при изменении знакового разряда операнда.
;поменять местами половинки регистра eax: mov ax,0ffff0000h mov cl,16 rol eax,cl ;eax=0000ffffh |
См. также: урок 9 и команды rcr, rcl, ror, sal, sar, shl, shr
ROR
Циклический сдвиг операнда вправо
ASCII-коррекция после сложения
Схема команды: | ror операнд,количество_сдвигов |
Назначение: операция циклического сдвига операнда вправо.
Синтаксис
Алгоритм работы:
- сдвиг всех битов операнда вправо на один разряд, при этом младший бит операнда вдвигается в операнд слева и становится значением старшего бита операнда;
- одновременно этот младший бит операнда становится значением флага переноса cf;
- старое значение флага переноса cf вдвигается в операнд слева и становится значением старшего бита операнда;
- указанные выше два действия повторяются количество раз, равное значению второго операнда.
Состояние флагов после выполнения команды:
OF | CF |
?r | r |
Применение:
Команда ror используется для циклического сдвига разрядов операнда вправо. Отличие этого сдвига от rcr в том, что очередной сдвигаемый бит одновременно вдвигается в операнд слева и становится значением флага cf. Так же, как и для других сдвигов, значение второго операнда (счетчика сдвига) ограничено диапазоном 0...31. Это объясняется тем, что микропроцессор использует только пять младших разрядов операнда количество_разрядов. Аналогично другим командам сдвига сохраняется эффект, связанный с поведением флага of, значение которого имеет смысл только в операциях сдвига на один разряд:
- если of=1, то текущее значение флага cf и вдвигаемого слева бита операнда различны;
- если of=0, то текущее значение флага cf и вдвигаемого слева бита операнда совпадают;
Этот эффект, как вы помните, обусловлен тем, что флаг of устанавливается в единицу всякий раз при изменении знакового разряда операнда.
;поместить четыре младших бита ax на место старших битов: ror ax,4 |
См. также: уроки 9 и команды rcl, rcr, ror, sal, sar, shl, shr
SAHF
(Store AH register into register Flags)
Загрузка регистра флагов eFlags/Flags из регистра AH
Схема команды: | sahf |
Назначение: запись содержимого регистра ah в младший байт регистра eflags/flags, в котором содержатся пять флагов cf, pf, af, zf и sf.
Синтаксис
Алгоритм работы:
Команда загружает младший байт регистра eflags/flags содержимым регистра ah. В битах 7, 6, 4, 2 и 0 регистра ah должны, соответственно, содержаться новые значения флагов sf, zf, af, pf и cf.
Состояние флагов после выполнения команды:
SF | ZF | AF | PF | CF |
r | r | r | r | r |
Применение:
Эта команда используется совместно с командой lahf. Из-за того, что регистр флагов непосредственно недоступен, сочетание этих команд можно применять для анализа — и, возможно, изменения — состояния некоторых флагов в регистре eflags/flags. Содержимое старшей части регистра флагов не изменяется.
;сбросить в ноль флаг cf lahf and ah,11111110b sahf |
См. также: уроки 2, 7 и команду lahf
SAL
(Shift Arithmetic operand Left)
Сдвиг арифметический операнда влево
Схема команды: | sal операнд,количество_сдвигов |
Назначение: арифметический сдвиг операнда влево.
Синтаксис
Алгоритм работы:
- сдвиг всех битов операнда влево на один разряд, при этом выдвигаемый слева бит становится значением флага переноса cf;
- одновременно справа в операнд вдвигается нулевой бит;
- указанные выше два действия повторяются количество раз, равное значению второго операнда.
Состояние флагов после выполнения команды:
OF | CF |
?r | r |
Применение:
Команда sal используется для сдвига разрядов операнда влево. Так же, как и для других сдвигов, значение второго операнда (счетчика сдвига) ограничено диапазоном 0...31. Это объясняется тем, что микропроцессор использует только пять младших разрядов количество_разрядов. Аналогично другим командам сдвига сохраняется эффект, связанный с поведением флага of, значение которого имеет смысл только в операциях сдвига на один разряд:
- если of=1, то текущее значение флага cf и выдвигаемого слева бита операнда различны;
- если of=0, то текущее значение флага cf и выдвигаемого слева бита операнда совпадают.
Этот эффект, как вы помните, обусловлен тем, что флаг cf устанавливается в единицу всякий раз при изменении знакового разряда операнда.
Команду sal удобно использовать для умножения целочисленных операндов без знака на степени 2. Кстати сказать, это самый быстрый способ такого умножения; умножить содержимое ax на 16 (2 в степени 4):
mov ax,17 sal ax,4 |
См. также: уроки 8, 9 и команды rcr, rcl, ror, rol, sar, shl, shr
SAR
(Shift Arithmetic operand Right)
Сдвиг арифметический операнда вправо
Схема команды: | sar операнд,количество_сдвигов |
Назначение: арифметический сдвиг операнда вправо.
Синтаксис
Алгоритм работы:
- сдвиг всех битов операнда вправо на один разряд, при этом выдвигаемый справа бит становится значением флага переноса cf;
- обратите внимание: одновременно слева в операнд вдвигается не нулевой бит, а значение старшего бита операнда, то есть по мере сдвига вправо освобождающиеся места заполняются значением знакового разряда. По этой причине этот тип сдвига и называется арифметическим;
- указанные выше два действия повторяются количество раз, равное значению второго операнда.
Состояние флагов после выполнения команды:
OF | CF |
?r | r |
Применение:
Команда sar используется для арифметического сдвига разрядов операнда вправо. Так же, как и для других сдвигов, значение второго операнда (счетчика сдвига) ограничено диапазоном 0...31. Это объясняется тем, что микропроцессор использует только пять младших разрядов операнда количество_разрядов. В отличие от других команд сдвига флаг of всегда сбрасывается в ноль в операциях сдвига на один разряд.
Команду sar можно использовать для деления целочисленных операндов со знаком на степени 2.
mov ax,88;(ax) разделить на 2 во второй степени, то есть на 4 sar ax,2 |
См. также: урок 8, 9 и команды rcr, rcl, ror, rol, sal, shl, shr
SBB
(SuBtract with Borrow)
Вычитание с заемом
Схема команды: | sbb операнд_1,операнд_2 |
Назначение: целочисленное вычитание с учетом результата предыдущего вычитания командами sbb и sub (по состоянию флага переноса cf).
Синтаксис
Алгоритм работы:
- выполнить сложение операнд_2=операнд_2+(cf);
- выполнить вычитание операнд_1=операнд_1-операнд_2;
Состояние флагов после выполнения команды:
OF | SF | ZF | AF | PF | CF |
r | r | r | r | r | r |
Применение:
Команда sbb используется для выполнения вычитания старших частей значений многобайтных операндов с учетом возможного предыдущего заема при вычитании младших частей значений этих операндов.
;выполнить вычитание 64-битных значений: vich_1-vich_2vich_1 dd 2 dup (0)vich_2 dd 2 dup (0)rez dd 2 dup (0)...;ввести значения в поля vich_1 и vich_2:;младший байт по младшему адресу... mov eax,vich_1 sub eax,vich_2 ;вычесть младшие половинки чисел mov rez,eax ;младшая часть результата mov eax,vich_1+4 sbb eax,vich_2+4 ;вычесть старшие половинки чисел mov rez+4,eax ;старшая часть результата |
См. также: урок 8, Приложение 7 и команды sub