Команды сдвига позволяют выполнять действия над отдельными битами операндов. Все команды сдвига перемещают биты в поле операндов влево или вправо. При выполнении команд сдвига флаг CF всегда содержит значение последнего выдвинутого бита. Рассмотрим следующие команды сдвига:
shr операнд, счетчик_сдвигов ; логический (беззнаковый) сдвиг вправо
shl операнд, счетчик_сдвигов ; логический (беззнаковый) сдвиг влево
В следующем примере команда shr сдвигает содержимое регистра al вправо на 1 бит. Выдвинутый в результате один бит попадает в флаг CF, а самый левый бит регистра al заполняется нулем.
mov al,10110111b ;в \verb!al! содержится 10110111
shr al,1 ;в \verb!al! содержится 01011011, \verb!CF=1!При сдвигах влево правые биты заполняются нулями.
Сдвиг влево на один двоичный разряд часто используется для удваивания чисел, а сдвиг на один разряд вправо — для деления на 2. Эти операции осуществляются значительно быстрее, чем команды умножения или деления.
Количество позиций, на которые должен быть выполнен сдвиг, задаются вторым аргументом инструкции сдвига, и может быть либо задано константой, либо регистром cl: например, shl ax, 12 или shl eax, cl.
Циклический сдвиг представляет собой операцию сдвига, при которой бит, выдвинутый с одного «конца» числа, занимает освободившийся разряд с другой стороны этого же числа. Существуют следующие команды циклического сдвига:
ror ; Циклический сдвиг вправо
rol ; Циклический сдвиг влево
rcr ; Циклический сдвиг вправо с переносом
rcl ; Циклический сдвиг влево с переносом
В командах rcr и rcl в сдвиге участвует флаг CF. Выдвигаемый из регистра бит заносится в флаг CF, а прежнее значение CF при этом поступает в освободившуюся позицию в регистре.
Команды and, or, xor и test являются командами логических операций. Эти команды имеют два операнда и используются для сброса, установки и проверки бит. Размерность операндов должна быть одинакова. Например, если размерность операндов равна слову (16 бит), то логическая операция выполняется сначала над нулевыми битами операндов, и далее над всеми битами с первого по пятнадцатый. Результат записывается на место первого операнда. Исключение составляет команда test. Команда test действует аналогично команде and, но результат не записывает на место первого операнда, а устанавливает только флаги во флаговом регистре. Это дает возможность анализировать отдельные биты не изменяя операнд.
| Таблица истинности для | and |
or |
xor |
|---|---|---|---|
| Значение операнда 1 | 0101 | 0101 | 0101 |
| Значение операнда 2 | 0011 | 0011 | 0011 |
| Результат операции | 0001 | 0111 | 0110 |
Команда or: Если хотя бы один из сравниваемых битов равен 1, то результат равен 1; если сравниваемые биты равны 0, то результат - 0. Команда 0. Команда and: Если оба из сравниваемых битов равны 1, то результат равен 1; во всех остальных случаях результат -xor: Если один из сравниваемых битов равен 0,а другой 1, то результат равен 1; если сравниваемые биты одинаковы (оба - 0 или оба - 1) то результат — 0.
Будем рассматривать байтную переменную flags как восемь независимых флагов, которые необходимо сбрасывать, устанавливать и анализировать в какой-либо программе. Для этого в правый операнд заносим «маску» в двоичной системе счисления. Рассмотрим пример установки второго бита с использованием команды or:
or flags, 00000100b ; второй бит = 1, остальные
; без измененийСбросить второй бит можно командой and, но маска должна быть инверсная:
and flags, 11111011b ; второй бит = 0, остальные
; без изменений
Для того чтобы проверить установлен ли нужный бит, применяется команда test:
test flags, 100b ; переменная \verb!flags! не изменилась
jz ... ; изменены \verb!ZF!, \verb!SF!, \verb!PF!Для сброса всех бит можно использовать команду xor:
xor ax, ax ; \verb!ах! --- обнуленЕще одна логическая команда not устанавливает обратное значение бит в байте или в слове, в регистре или в памяти: нули становятся единицами, а единицы — нулями. Если, например, регистр al содержит 1100 0101, то команда not al изменяет это значение на 0011 1010.
Написать программу со следующим алгоритмом:
- вывести приглашение;
- ввести с клавиатуры строку (предполагается, что она содержит десятичные цифры и любые буквы);
- найти во введенной строке все цифры и для каждой найденной цифры установить в «1» в регистре
axбит, номер которого равен этой цифре; - вывести на экран содержимое регистра
axв виде нулей и единиц; - объяснить полученный результат.