Арифметические действия. Логические операции. Единицы количества информации. Коды чисел

Фундаментальные основы цифровой обработки: представление двоичных данных в аппаратных узлах, логика арифметико-логического устройства, кодирование целых чисел и различение ёмкости памяти от интерпретируемого значения.

1. Единицы количества информации: мера хранилища и семантика данных

В архитектуре вычислительных машин физические накопители и регистры оперируют дискретными элементарными состояниями. Минимальной неделимой единицей количества информации является бит (binary digit, бит) — логический элемент, принимающий одно из двух взаимоисключающих физических состояний (уровень логического нуля 0 В или логической единицы ~3.3/5 В).

Совокупность из 8 последовательных бит образует байт (октет), который служит базовой единицей адресации оперативной памяти в большинстве современных вычислительных систем. Для описания больших объёмов используются кратные единицы:

Наименование Двоичное соотношение (IEC / ГОСТ) Точный объём в байтах Область применения в архитектуре
1 Байт (Byte) $2^0$ байт = 8 бит 1 байт Минимальная адресуемая ячейка памяти
1 Килобайт (Кбайт / KiB) $2^{10}$ байт = $1024$ байта 1 024 байта Кэш-память L1 инструкций/данных, сегменты
1 Мегабайт (Мбайт / MiB) $2^{20}$ байт = $1024$ Кбайт 1 048 576 байт Кэш-память L2/L3, буферы видеопамяти
1 Гигабайт (Гбайт / GiB) $2^{30}$ байт = $1024$ Мбайт 1 073 741 824 байта Оперативная память (DRAM), адресное пространство
1 Терабайт (Тбайт / TiB) $2^{40}$ байт = $1024$ Гбайт 1 099 511 627 776 байт Энергонезависимые накопители (SSD, NVMe, HDD)

Ключевое архитектурное различие: Единица количества информации (бит, байт) измеряет ёмкость физической ячейки или линии связи. Она не определяет, что именно закодировано в ячейке. Последовательность из 8 бит 11111111 занимает ровно 1 байт памяти, но её математическое и практическое значение целиком определяется командой процессора: для беззнаковой операции это $255_{10}$, для знаковой операции в дополнительном коде — $-1_{10}$, а для текстового вывода в таблице Windows-1251 — буква «я».

2. Коды чисел в ЭВМ: прямой, обратный и дополнительный

Для представления чисел в регистрах процессора используется фиксированная разрядная сетка (8, 16, 32 или 64 бита). В беззнаковом представлении все $n$ разрядов кодируют величину числа в диапазоне от $0$ до $2^n - 1$. Для работы со значащими отрицательными числами выделяется старший бит (Most Significant Bit, MSB): 0 обозначает положительное число или нуль, 1 — отрицательное число.

Прямой код (Sign-Magnitude)

Старший разряд — знак, остальные $n-1$ разрядов содержат двоичный модуль числа.

Проблема: Наличие двух нулей ($+0$ как 00000000 и $-0$ как 10000000), сложность аппаратной реализации вычитания (требуется отдельный вычитатель).

Обратный код (Ones' Complement)

Для отрицательного числа знаковый бит равен 1, а все разряды модуля побитово инвертируются ($0 \to 1, 1 \to 0$).

Проблема: Сохраняется двойственность нуля ($00000000$ и $11111111$), при сложении требуется циклический перенос единицы (end-around carry).

Дополнительный код (Two's Complement)

Для отрицательного числа берётся обратный код и к младшему разряду прибавляется 1: $[X]_{доп} = [X]_{обр} + 1$.

Преимущество: Единственный нуль, операция вычитания заменяется сложением с отрицательным числом на стандартном сумматоре без дополнительных схем!

Подробный алгоритм формирования дополнительного кода (8-битная сетка)

Рассмотрим число $-43_{10}$:

  1. Модуль числа: $|-43| = 43_{10} = 32 + 8 + 2 + 1 = 00101011_2$.
  2. Прямой код: Устанавливаем знаковый бит в единицу: 10101011.
  3. Обратный код: Инвертируем младшие 7 бит модуля: 11010100.
  4. Дополнительный код: Прибавляем единицу к младшему разряду:
        11010100 (обратный код)
      + 00000001
      ----------
        11010101 (дополнительный код числа -43)
                

Формула весов для дополнительного кода: Старший бит $b_7$ имеет отрицательный вес $-2^7 = -128$:

Значение = -128 * 1 + 64 * 1 + 32 * 0 + 16 * 1 + 8 * 0 + 4 * 1 + 2 * 0 + 1 * 1
         = -128 + 64 + 16 + 4 + 1 = -128 + 85 = -43.

3. Двоичные арифметические действия в АЛУ и флаги состояний

Арифметико-логическое устройство (АЛУ) выполняет операции сложения с помощью комбинационных сумматоров. Вычитание $A - B$ аппаратно реализуется как сложение $A + [-B]_{доп}$.

Пример аппаратного сложения $58_{10} + (-43_{10})$:

Представим $58_{10}$ в двоичном виде: $58 = 32 + 16 + 8 + 2 = 00111010_2$. Значение $[-43]_{доп} = 11010101_2$.

  Разряды переноса: 1 1 1 1   1 
             A:     0 0 1 1 1 0 1 0   (+58)
           + B:     1 1 0 1 0 1 0 1   (-43 в доп. коде)
  ---------------------------------
             Сумма: 1 0 0 0 0 1 1 1 1   (+15 в 8 битах, перенос 1 отбрасывается)
        

В 8-разрядном регистре фиксируется значение 00001111, что в точности соответствует $+15_{10}$. Перенос за пределы 8 разрядов естественным образом аннулирует избыточный базис $2^8 = 256$.

Флаги регистра состояния процессора (FLAGS / EFLAGS)

После каждого арифметического действия процессор выставляет аппаратные флаги:

  • CF (Carry Flag — флаг переноса): Устанавливается в 1, если произошел перенос из старшего разряда или заём при вычитании. Критичен для беззнаковой арифметики.
  • OF (Overflow Flag — флаг переполнения): Устанавливается в 1, если результат операции вышел за пределы допустимого диапазона знаковых чисел ($[-128 \dots +127]$ для 8 бит). Вычисляется логической операцией исключающего ИЛИ переноса в знаковый бит и переноса из знакового бита: $OF = C_{n-1} \oplus C_n$.
  • ZF (Zero Flag — флаг нуля): Равен 1, если результат равен точно нулю.
  • SF (Sign Flag — флаг знака): Копирует значение старшего знакового бита результата (1 — отрицательный результат).

4. Поразрядные логические операции: маскирование и манипуляция битами

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

Конъюнкция: AND (&)

Результат 1 только если оба бита равны 1. Применяется для сброса и маскирования ненужных битов (умножение на 0 обнуляет бит, умножение на 1 сохраняет).

Дизъюнкция: OR (|)

Результат 1, если хотя бы один бит равен 1. Применяется для принудительной установки конкретных битов в 1 без изменения остальных разрядов.

Исключающее ИЛИ: XOR (^)

Результат 1, если биты различны. Применяется для инвертирования выбранных битов по маске, а также для быстрого обнуления регистра (XOR EAX, EAX).

Инверсия: NOT (~)

Унарная операция: заменяет каждый 0 на 1 и каждую 1 на 0. Основа получения обратного кода.

Пример работы с регистром управления периферийного устройства:

Пусть текущее состояние регистра порта ввода-вывода равно $R = 11011010_2$.

1. Выделение младших 4 бит (маска 00001111):
       R:    11011010
   AND M:    00001111
   ------------------
   Результат: 00001010 (старшие биты гарантированно обнулены)

2. Установка бита готовности (бит 0) и питания (бит 5) (маска 00100001):
       R:    11011010
    OR M:    00100001
   ------------------
   Результат: 11111011 (биты 0 и 5 стали 1, остальные не изменились)
        

5. Вопросы для самопроверки

  • Почему физический размер ячейки памяти в 1 байт не позволяет судить о том, число или символ там хранится?
  • В чём заключается аппаратное преимущество дополнительного кода перед прямым при построении АЛУ?
  • Какое правило используется для обнаружения знакового переполнения ($OF$) при сложении двух двоичных чисел?
  • Какую логическую операцию и с какой битовой маской необходимо применить, чтобы гарантированно сбросить в 0 старшую тетраду 8-битного регистра?