Читать «Assembler. Программирование на языке ассемблера IBM PC» онлайн - страница 35

Unknown Author

Из сказанного следует, что в ЭВМ, где знаковые числа представляются в дополнительном коде, не нужны разные машинные команды для сложения и вычитания беззнаковых и знаковых чисел, достаточно и одного набора этих команд. (В этом важное преимущество дополнительного кода над другими способами представления знаковых чисел.)

Однако не все так просто при сложении и вычитании знаковых чисел, здесь есть свои неприятности. Напомним, что при размере ячеек в 8 битов в дополнительном коде представляются только числа от -128 до +127. Рассмотрим, к примеру, сложение знаковых чисел +127 и +2. Складывая их как беззнаковые числа 127 и 2, получаем величину 129, которую теперь надо рассмотреть как дополнительный код ответа: поскольку 129=256-127, то суммой должно быть признано число -127. Таким образом, складывая два положительных числа, мы получили отрицательное число!

Почему так произошло? При представлении чисел (размером в байт) в дополнительном коде левый разряд ядляется знаковым, а на модуль числа отводится 7 правых разрядов. У нас же получился ответ 129=1000000lb, модуль которого не вмещается в эти 7 разрядов, поэтому модуль и "залез" в знаковый разряд, изменив его на противоположный.

Такое налезание модуля (мантиссы, цифровой части) числа на знаковый разряд называют "переполнением мантиссы". В общем случае оно происходит, если складываются числа одного знака и настоящая сумма оказывается вне диапазона представимых знаковых чисел ([-128, +127] при к=8). Переполнение мантиссы фиксируется в флаге переполнения OF: рн получает значение 1, если было переполнение, и значение 0 иначе* Таким образом, при OF=Q результат правильный, а при OF=l - неправильный, однако эта ошибка не фиксируется и "поймать" ее можно только последующим анализом флага OF.

Аналогичное переполнение мантиссы возможно и при вычитании. Например, при вычитании (+127)-(-2) = 127+2 получаем 129, а это дополнительный код числа -127, которое и выдается как результат вычитания, хотя истинной разностью является число 129. В общем случае переполнение мантиссы происходит, если вычитаются числа разных знаков и настоящая разность оказалась вне диапазона представимых знаковых чисел. И здесь факт переполнения фиксируется в флаге OF: он получает значение 1, если было переполнение мантиссы и результат операции неправильный, и значение 0, если не было переполнения и ответ правильный.

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

И еще одно замечание. Поскольку сложение и вычитание беззнаковых и знаковых чисел производятся по одним и тем же алгоритмам и поскольку ПК заранее не знает, какие именно числа он складывает или вычитает, то при выполнении этих операций ПК одновременно фиксирует в флагах CF и OF особенности операций для обоих классов чисел. Какие именно числа складываются (вычитаются), знает только автор программы, он и должен решать, на какой из этих двух флагов следует реагировать. Если он считает, что складываются беззнаковые числа, то для него представляет интерес флаг CF (был ли перенос) и безразличен флаг OF, но если, по его мнению, складываются знаковые числа, то он должен интересоваться флагом OF (было ли переполнение мантиссы) и не должен обращать внимание на флаг CF.