Реклама:

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

Очень полезны команды сдвига и циклического сдвига. Они часто даются в нескольких вариантах. Сдвиги - это операции, при которых биты сдвигаются влево или вправо, при этом биты, которые сдвигаются за пределы слова, утрачиваются. Циклические сдвиги - это сдвиги, при которых биты, вытесненные с одного конца, появляются на другом конце слова. Разницу между обычным сдвигом и циклическим сдвигом иллюстрирует следующий пример:

А:

00000000 00000000 00000000 01110011 Сдвиг А вправо на 2 бита:

00000000 00000000 00000000 00011100 Циклический сдвиг А вправо на 2 бита:

11000000 00000000 00000000 00011100

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

Сдвиги вправо часто выполняются с расширением по знаку. Это значит, что позиции, освободившиеся на левом конце слова, заполняются знаковым битом (О или 1) исходного слова, как будто знаковый бит перетаскивают вправо. Кроме того, это значит, что отрицательное число остается отрицательным. Вот как выглядят сдвиги на 2 бита вправо:

А:

1111111 11111111 11111111 11110000 А сдвигается без знакового расширения:

0011111 11111111 11111111 11111100 А сдвигается со знаковым расширением:

1111111 11111111 11111111 11111100

Операция сдвига используется при умножении и делении на 2. Если положительное целое число сдвигается влево на & бит, результатом будет исходное число, умноженное на 2к. Если положительное целое число сдвигается вправо на & бит, результатом становится исходное число, деленное на 2к.

Сдвиги могут использоваться для повышения скорости выполнения некоторых арифметических операций. Рассмотрим выражение 18 х п, где п - положительное целое число: 18 х я = 16хгг + 2хгг. Значение 16 х п можно получить путем сдвига копии п на 4 бита влево. Значение 2 х п можно получить, сдвинув п на 1 бит влево. Сумма этих двух чисел равна 18 х гг. Таким образом, целиком произведение можно вычислить путем одного перемещения, двух сдвигов и одного сложения, что обычно выполняется гораздо быстрее, чем операция умножения. Конечно, компилятор может применить такую схему, только если один из множителей является константой.

Сдвиг отрицательных чисел даже со знаковым расширением дает совершенно другие результаты. Рассмотрим, например, число -1 в обратном двоичном коде. При сдвиге влево на 1 бит получается число -3. При сдвиге влево еще на 1 бит получается число -7:

Число -1 в обратном двоичном коде:

11111111 11111111 11111111 11111110 Число -1 сдвигается влево на 1 бит (-3):

11111111 11111111 11111111 11111100 Число -1 сдвигается влево на 2 бита (-7):

11111111 11111111 11111111 11111000

Сдвиг влево отрицательных чисел в обратном двоичном коде не ведет к умножению числа на 2. В то же время сдвиг вправо корректно обеспечивает деление.

А теперь рассмотрим число -1 в дополнительном двоичном коде. При сдвиге вправо на 6 бит с расширением по знаку получается число -1, что неверно, поскольку целая часть от -1/64 равна 0:

Число -1 в дополнительном двоичном коде:

11111111 11111111 11111111 11111111 Число -1, сдвинутое влево на 6 бит, равно -1:

11111111 11111111 11111111 11111111

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

Операции циклического сдвига нужны для манипулирования последовательностями битов в словах. Чтобы проверить все биты в слове, каждый бит путем циклического сдвига слова поочередно помещается в знаковый разряд, где его можно легко проверить; когда все биты будут проверены, восстанавливается изначальное значение слова. Операции циклического сдвига гораздо удобнее операций обычного сдвига, поскольку при этом не теряется информация: произвольная операция циклического сдвига может быть отменена операцией циклического сдвига в противоположную сторону.

В некоторых бинарных операциях обычно используются совершенно определенные операнды, поэтому для быстрого выполнения аналогичных действий в архитектуры команд часто включаются унарные операции. Например, в начале вычислений чрезвычайно часто требуется перемещение нуля в память или в регистр. Перемещение нуля - это особый случай команды перемещения данных. Поэтому для повышения производительности в архитектуру вводится операция CLR с единственным операндом - адресом той ячейки, которую нужно очистить (то есть установить на 0).

Прибавление 1 к слову тоже часто требуется при различных подсчетах. Унарная форма команды ADD - это операция инкремента INC. Другой пример - операция NEG. Отрицание X - это на самом деле бинарная операция вычитания 0 - X, но поскольку операция отрицания применяется очень часто, в архитектуру команд вводится команда NEG. Важно понимать разницу между арифметической операцией NEG и логической операцией NOT. При выполнении операции NEG происходит аддитивная инверсия числа (такое число, сумма которого с исходным числом дает 0). При выполнении операции NOT все биты в слове просто инвертируются. Эти операции очень похожи, а для системы, в которой отрицательные величины представлены в обратном двоичном коде, они идентичны. (В арифметике дополнительных кодов для выполнения команды NEG сначала инвертируются все биты, а затем к полученному результату прибавляется 1.)

Унарные и бинарные операции часто объединяются в группы по функциям, которые они выполняют, а вовсе не по числу операндов. В первую группу входят арифметические операции, в том числе операция отрицания. Во вторую группу входят логические операции и операции сдвига, поскольку эти две категории очень часто используются вместе для извлечения данных.

Бинарные операции || Оглавление || Сравнения и условные переходы