Команды сдвига позволяют выполнять действия над отдельными битами операндов. Все команды сдвига перемещают биты в поле операндов влево или вправо. При выполнении команд сдвига флаг 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
в виде нулей и единиц; - объяснить полученный результат.