Логические операции используются для сброса и установки битов и для арифметических операций в коде 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.