4.4. Логические операции и команды сдвига

Логические операции используются для сброса и установки битов и для арифметических операций в коде ASCII. Команды логических операций AND, OR, XOR, NOT, TEST обрабатывают байт или слово, в регистре или в памяти, и воздействуют на флаги CF, OF, а остальные флаги зависят от результата операции. В командах:

and    операнд1, операнд2           ;поразрядное логическое умножение

or     операнд1, операнд2           ;поразрядное логическое сложение

cor    операнд1, операнд2           ;поразрядное сложение по модулю 2

not    операнд                      ;поразрядное логическое не

Результат выполнения операции записывается в первый операнд. Команда test действует как and, кроме того, что результат выполнения поразрядного логического умножения не записывается на место первого операнда.

Пример 1. Пусть значение регистра AL равно 10b. Тогда команда

and    al,01b

запишет в al число 00b. Флаги будут равны: CF=0, OF=0, PF=0, SF=0, ZF=0. Команда

     or     al,01b

запишет в al число 11b и даст флаги: CF=0, OF=0, PF=1, SF=1, ZF=0. Команда

     xor    al,01b

запишет в al число 10000101b и даст флаги: CF=0, OF=0, PF=1, SF=1, ZF=0. Команда

     xor    al,01b

запишет в al число 10000101b и даст флаги: CF=0, OF=0, PF=0, SF=1, ZF=0. Команда

     not    al

изменит значение al на 01b, даст флаги CF=0,OF=0,PF=1,SF=0,ZF=0. Наконец,

     test   al,01b

не изменит al, но установит флаги как команда and.

Команды сдвига и циклического сдвига имеют следующий формат:

код    операнд1, счётчик

где счетчик равен 1 или CL. Действие команд сдвига показано на рис. 4.1. Операндом команды сдвига является байт или слово.    

shr       сдвиг вправо                                               

            sar       арифметический сдвиг вправо                  

            shr/sal  сдвиг влево                                                 

            ror       циклический сдвиг вправо                        

            rol        циклический сдвиг влево                          

            rcr        циклический сдвиг вправо через перенос           

            rcl        циклический сдвиг влево через перенос 

Рис. 4.1. Команды сдвига

При выполнении команд сдвига флаг CF всегда содержит значение последнего выдвинутого бита.

Пример 2. Пусть AL=BL=10001000b. Тогда команды

shr    al,1

sur    bl,1

запишут в CF значение 0, преобразуют AL в число 00b, а BL – в число 11000100b.

При тех же условиях, команды

mov    cl,5

rol    al,cl

сдвигают содержимое AL влево 5 раз, перенося каждый раз старший бит в младший. Флаг CF последовательно принимает значения 1,0,0,0,1. В результате al=00b.

Команда сдвига влево используется для умножения операнда на 2. Рассмотрим следующее приложение для умножения на 2 числа, состоящего из 32 бит и находящегося в двух регистрах:

Пусть число находится в регистровой паре DX:AX так, что старшие 16 бит находятся в DX, а младшие – в AX. Следующие команды

shl    ax,1

rcl   dx,1

умножают это число на 2. Здесь вторая команда переносит бит CF в младший бит регистра DX, после того как бит CF был извлечен из старшего бита регистра AX.

Применим команду сдвига влево для вывода слова в двоичном виде.

Пример 3. Напишем программу, содержащую команды, выводящие на экран двоичное представление регистра bx.

<1>        title usdv.exe

<2> code segment

<3>        assume     cs:code, ds:code

<4>        mov  bx,101b     ;произвольное число

<5>        mov  cx,16             ;вывести 16 бит

<6> lp1:   mov   dl,’0’            ;ASCII-код нуля

<7>        shl  bx,1              ;сдвиг влево

<8>        jnc  lp2               ;если старший бит был равен 0

<9>        add  dl,1              ;иначе dl=’1’

<10> lp2:   mov   ah,2              ;вывод символа из dl

<11>        int  21h               ;на экран

<12>        loop lp1

<13>        mov  ax,4c00h          ;выход

<14>        int  21h

<15> code   ends

<16>        end

В результате на экран будет выведено число 0000001001. В данной программе для вывода символа из dl была применена функция 2 прерывания 21h.