Особенности выполнения арифметических операций. Беззнаковые числа складываются по правилам двоичной арифметики. Однако факт переполнения разрядной сетки не фиксируется. Вместо этого единица переноса отбрасывается и в качестве ответа выдается искаженная сумма, а флаг CF устанавливается в 1 (если переноса не было, флаг обнуляется). Такое суммирование без учета единицы переноса называется суммированием по модулю 2k (k - размер ячейки):
При вычитании беззнаковых целых чисел при х у выполняется обычное вычитание. При х < у числу х дается заем единицы (к числу х прибавляется величина 2k) и затем производится вычитание. Ошибка не фиксируется, но флаг переноса CF устанавливается в 1. Такое вычитание называют вычитанием по модулю 2k:
Например, при k=8 вычитание 1-2 происходит таким образом:
(28 + 1) – 2 = (256 + 1) – 2 = 257 – 2 = 255
(в двоичной системе замена 1 на 256+1 есть замена 00000001 на 100000001, т.е. добавление 1 слева) и число 255 объявляется результатом вычитания.
Рассмотрим сложение и вычитание знаковых чисел. Если целые числа со знаком представлены в дополнительном коде, то складывать и вычитать их следует по алгоритмам беззнаковых чисел. Дополнительные коды знаковых операндов рассматривают как числа без знака и в таком виде их складывают или вычитают, а полученный результат затем рассматривают в дополнительном коде.
Например, пусть надо сложить +3 и -1 (ячейка 8 бит). Их дополнительные коды – 3 и (256-1)=255. Складываем числа как беззнаковые: 3+255 (mod 256) = 258 (mod 256) = 2. Величина 2 рассматривается как дополнительный код ответа, поэтому получаем ответ +2.
Таким образом, если знаковые числа представлены в дополнительном коде, то не нужны разные машинные команды для сложения и вычитания беззнаковых и знаковых чисел, достаточно одного набора команд. В этом и заключается преимущество дополнительного кода над другими способами представления знаковых чисел.
При представлении чисел (например, размером в байт) в дополнительном коде левый разряд является знаковым, а на модуль числа отводится 7 правых разрядов. При сложении возможно возникновение «переполнение мантиссы» – переход модуля числа (мантиссы) в знаковый разряд.
В общем случае переполнение мантиссы происходит, если слагаемые одного знака и сумма оказывается вне диапазона представимых знаковых чисел ([-128, +127] при k=8). Рассмотрим сложение знаковых чисел +127 и +2. Складывая их как беззнаковые числа 127 и 2, получим число 129, которое теперь надо рассматривать как дополнительный код ответа. Поскольку 129=256-127, то суммой должно быть число -127. В результате, складывая два положительных числа, получили отрицательное; ответ равен 129=10000001b и его модуль не помещается в 7 разрядов, поэтому он перешел в знаковый разряд, изменив его на противоположный.
Переполнение мантиссы возможно и при вычитании. Например, при вычитании (+127)-(-2) = 127+2 получаем 129, а это дополнительный код числа -127, которое и выдается как результат вычитания, хотя истинной разностью является число 129. Такое переполнение мантиссы фиксирует флаг переполнения OF: он устанавливается в 1, если переполнение имело место.
Таким образом, при сложении беззнаковых чисел, интерес представляет флаг переноса CF, но если складываются знаковые числа, то анализу подлежит флаг OF (переполнение мантиссы).
При сложении и вычитании чисел меняются также флаг нуля ZF и флаг знака SF. Флаг ZF устанавливается в 1, если результат оказался нулевым, и сбрасывается в 0, если результат ненулевой. Флаг SF содержит знаковый (самый левый) бит результата. Он полезен при работе со знаковыми числами, т.к. устанавливается в 1, если результат отрицательный, и сбрасывается 0 в противном случае.
Do'stlaringiz bilan baham: |