Набор команд процессора содержит логические инструкции AND, OR, XOR, TEST и NOT, которые проверяют, устанавливают и очищают биты в соответствии с потребностями программы.
Логические инструкции
Синтаксис использования логических инструкций следующий:
AND операнд1, операнд2
OR операнд1, операнд2
XOR операнд1, операнд2
TEST операнд1, операнд2
NOT операнд1
Во всех случаях первый операнд находится либо в регистре, либо в памяти. Второй операнд может находиться либо в регистре/памяти, либо являться константой. Тем не менее, операции типа «память-в-память» невозможны.
Инструкция AND
Инструкция AND выполняет побитовую операцию И. Побитовая операция И возвращает 1
, если совпадающие биты обоих операндов равны 1
, в противном случае — возвращается 0
. Например:
Операнд №1: 0101
Операнд №2: 0011
--
После применения AND -> Операнд №1: 0001
Операция AND может быть использована для сброса одного или нескольких бит. Например, допустим, что регистр BL содержит 0011 1010
. Если вам необходимо сбросить старшие биты в ноль, то вы выполняете операцию AND между этим регистром и числом 0FH
:
1 |
AND BL, 0FH ; эта строка устанавливает для регистра BL значение 0000 1010 |
Давайте рассмотрим другой пример. Если вы хотите проверить, является ли определенное число чётным или нечётным, то с помощью простого теста вы сможете проверить младший значимый бит числа. Если им окажется 1
, то число нечётное, если же 0
— число чётное.
Например, если число находится в регистре AL, то мы можем написать следующее:
1 2 |
AND AL, 01H ; выполняем операцию AND с 0000 0001 JZ EVEN_NUMBER |
Следующая программа это проиллюстрирует:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
Live Demo section .text global _start ; должно быть объявлено для использования gcc _start: ; сообщаем линкеру входную точку mov ax, 8h ; записываем 8 в регистр AX and ax, 1 ; выполняем операцию AND с AX jz evnn mov eax, 4 ; номер системного вызова (sys_write) mov ebx, 1 ; файловый дескриптор (stdout) mov ecx, odd_msg ; сообщение для вывода на экран mov edx, len2 ; длина сообщения int 0x80 ; вызов ядра jmp outprog evnn: mov ah, 09h mov eax, 4 ; номер системного вызова (sys_write) mov ebx, 1 ; файловый дескриптор (stdout) mov ecx, even_msg ; сообщение для вывода на экран mov edx, len1 ; длина сообщения int 0x80 ; вызов ядра outprog: mov eax,1 ; номер системного вызова (sys_exit) int 0x80 ; вызов ядра section .data even_msg db 'Even Number!' ; сообщение с чётным числом len1 equ $ - even_msg odd_msg db 'Odd Number!' ; сообщение с нечётным числом len2 equ $ - odd_msg |
Результат выполнения программы:
Even Number!
Изменяем значение в регистре AX, указав нечётную цифру:
1 |
mov ax, 9h ; записываем 9 в регистр AX |
И результат:
Odd Number!
Вы можете точно так же очистить весь регистр, используя AND с 00H
.
Инструкция OR
Инструкция OR выполняет побитовую операцию ИЛИ. Побитовый оператор ИЛИ возвращает 1
, если совпадающие биты одного или обоих операндов равны 1
, и возвращает 0
, если оба бита равны нулю. Например:
Операнд №1: 0101
Операнд №2: 0011
--
После применения OR -> Операнд №1: 0111
Операция OR может быть использована для указания одного или нескольких бит. Например, допустим, что регистр AL содержит 0011 1010
, и нам необходимо установить четыре младших бита. Мы можем сделать это, используя оператор OR со значением 0000 1111
(т.е. с регистром FH):
1 |
OR BL, 0FH ; эта строка устанавливает для BL значение 0011 1111 |
В качестве другого примера давайте сохраним значения 5
и 3
в регистрах AL и BL соответственно. Таким образом, следующая инструкция:
1 |
OR AL, BL |
Должна сохранить 7
в регистре AL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
section .text global _start ; должно быть объявлено для использования gcc _start: ; сообщаем линкеру входную точку mov al, 5 ; записываем 5 в регистр AL mov bl, 3 ; записываем 3 в регистр BL or al, bl ; выполняем операцию OR с регистрами AL и BL, результатом должно быть число 7 add al, byte '0' ; выполняем конвертацию из десятичной системы в ASCII mov [result], al mov eax, 4 mov ebx, 1 mov ecx, result mov edx, 1 int 0x80 outprog: mov eax,1 ; номер системного вызова (sys_exit) int 0x80 ; вызов ядра section .bss result resb 1 |
Результат выполнения программы:
Инструкция XOR
Инструкция XOR выполняет побитовую операцию XOR. Побитовая операция XOR возвращает 1
, если биты операндов являются различными, если же они являются одинаковыми (оба равны 0
или 1
), то возвращается 0
. Например:
Операнд №1: 0101
Операнд №2: 0011
--
После применения XOR -> Операнд №1: 0110
Следующая инструкция очищает регистр (сбрасывает все биты в 0
):
1 |
XOR EAX, EAX |
Инструкция TEST
Инструкция TEST работает так же, как и инструкция AND, но, в отличие от инструкции AND, она не изменяет первый операнд. Таким образом, если нам нужно проверить, является ли число в регистре чётным или нечётным, мы можем сделать это, используя инструкцию TEST, без необходимости изменять исходное число:
1 2 |
TEST AL, 01H JZ EVEN_NUMBER |
Инструкция NOT
Инструкция NOT выполняет побитовую операцию НЕ. Побитовая операция НЕ изменяет биты операнда на противоположные. Операнд может находиться либо в регистре, либо в памяти. Например:
Операнд №1: 0101 0011
--
После применения NOT -> Операнд №1: 1010 1100