Команда NOT

Используется для инверсии отдельных битов единственного операнда, который может быть регистром или памятью. Соответственно команда может быть записана в трех различных форматах:

NOT r/m8 NOT r/m16 NOT r/m32

Таблица истинности для оператора NOT приведена ниже (табл. 8.1).

Табл. 8.1

a b a AND b a OR b a XOR b NOT a

 

8.3. Массивы битов (разрядные матрицы)

Любое число можно записать в двоичной системе в виде последовательности нулей и единиц. Например, любое 16-разрядное число состоит из 16 двоичных цифр: 0 и 1. Мы можем использовать одно число для хранения шестнадцати различных состояний — флагов. Нам не нужно тратить место на хранение 16 различных переменных, ведь для описания состояния (включено/выключено) вполне достаточно 1 бита. Переменная, используемая для хранения флагов, называется разрядной матрицей или массивом битов.

Высокоуровневые языки программирования также используют разрядные матрицы, например, при хранении набора значений перечисления, для экономии памяти. Мы уже знакомы с одной разрядной матрицей, которая очень часто используется в программировании — это регистр признаков микропроцессора EFLAGS. Мы будем очень часто сталкиваться с разрядными матрицами при программировании различных устройств: видеоадаптера, звуковой платы и т.д. В этом случае изменение одного бита в разрядной матрице может изменить режим работы устройства.

Для изменения значения отдельных битов в матрице служат логические операции. Первый операнд задает разрядную матрицу, с которой мы будем работать, а второй операнд задает так называемую маску, используемую для выбора отдельных битов.

Для установки определенных битов массива в единицу (все остальные биты при этом должны остаться без изменения) применяется команда OR. В качестве маски возьмите двоичное число, в котором единицы стоят на месте тех битов, которые вы хотите установить в массиве. Например, если вы хотите установить первый и последний биты массива, вы должны использовать маску 10000001b. Все остальные биты останутся нетронутыми, поскольку 0 OR x всегда возвращает x.

Чтобы сбросить некоторые биты (установить их значение в 0) применяется команда AND. В качестве маски необходимо число, в котором нули стоят на месте тех битов, которые вы хотите сбросить, а единицы — во всех остальных позициях. Поскольку 1 AND x всегда возвращает x, то установятся в 0 только необходимые нам биты.

Пример 1. В регистре AL загружен массив битов. Нужно установить все нечетные позиции в 1. Предыдущее состояние массива неизвестно.

or al,10101010b ;маска устанавливает все нечетные биты в 1

Пример 2. В массиве битов, хранящемся в регистре AL, сбросить 0-й и 7-й биты, все остальные оставить без изменения. Исходное состояние массива также неизвестно.

and al,01111110b ;каждая 1 в маске сохраняет бит в ее позиции

С помощью XOR также можно изменять значения битов, не зная предыдущего состояния. Для этого в маске установите 1 для каждого бита, который вы хотите инвертировать (0 станет 1, а 1 станет 0), а для всех оставшихся битов установите 0. Если мы выполним XOR дважды, то получим исходное значение.

Такое поведение операции XOR позволяет использовать эту команду для простого шифрования: к каждому байту шифруемых данных применяется XOR с постоянной маской (ключом), а для дешифровки тот же ключ применяется (XOR) к шифрованным данным.