Целые числа
Мы уже знаем, что хранимые в памяти машинные слова (наборы битов) могут трактоваться по-разному. При вызове в устройство управления этот набор битов трактуется как команда, а при вызове в арифметико-логическое устройство – как число. В дополнении к этому в рассматриваемой нами архитектуре каждое хранимое в памяти целое число может трактоваться программистом как знаковое или беззнаковое (неотрицательное). По внешнему виду невозможно определить, какое число храниться в определённом месте памяти, только сам программист может знать, как он рассматривает это число. Таким образом, определены две машинные системы счисления для представления знаковых и беззнаковых чисел соответственно.
Беззнаковые (неотрицательные) числа представляются в уже известной Вам двоичной системе счисления, такое представление называется прямым кодом неотрицательного числа. Например, десятичное число 13, хранимое в одном байте, будет записано как прямой код 00001101.
Если инвертировать прямой код (т.е. заменить все "1" на "0", а все "0" на "1"), то получим так называемый обратный код числа. Например, обратный код числа 13 равен 11110010.
Для представления отрицательных знаковых чисел используется так называемый дополнительный код, который можно получить из дополнительного кода прибавлением единицы. Например, получим дополнительный код числа –13:
Прямой код = 00001101
Обратный код = 11110010
+ 1
Дополнительный код = 11110011
Существует и другой алгоритм преобразования отрицательного числа X в дополнительный код. Для этого необходимо записать в прямом коде значение 2N -|X|, где значение N равно максимальному числу бит в представлении числа (в нашем примере N=8).
Итак, в знаковой системе счисления отрицательные числа представляются в дополнительном коде, а неотрицательные – в прямом коде. Заметим, что при знаковой трактовке целых чисел крайний правый бит определяет знак числа ("1" для отрицательных чисел). Этот бит называется знаковым битом целого числа. Для знаковых чисел числовая ось несимметрична: количество отрицательных чисел на единицу больше, чем количество положительных чисел (докажите это !).
Процесс перехода от прямого кода к дополнительному коду и обратно с технической точки зрения очень прост и может быть легко реализован в центральном процессоре.
Очень важно понять, что все арифметические операции над знаковыми и беззнаковыми целыми числами производятся абсолютно по одинаковым алгоритмам, что естественно, потому что центральный процессор "не знает", какие это числа "на самом деле". В то же время, с точки зрения программиста, результаты таких операций могут быть разными для знаковых и беззнаковых чисел. Рассмотрим примеры сложения двух чисел длиной в байт. В первом столбике записано внутреннее двоичное представление чисел, а во втором и третьем – беззнаковое и знаковое десятичное представления этих же чисел.
· Пример 1.
Б/з. | Знак. | |
–4 | ||
Из этого примера видно, что для знаковой трактовки чисел операция сложения выполнена правильно, а при рассмотрении чисел как беззнаковые результат будет неправильным, так как мы получим девятизначное двоичное число, не "умещающееся" в один байт. Так как центральный процессор "не знает", как программист будет трактовать складываемые числа, то он "на всякий случай" сигнализирует о том, что при сложении беззнаковых чисел произошла ошибка.
Для обозначения таких (и некоторых других) ситуаций в архитектуре компьютера введено понятие флагов. Каждый флаг занимает один бит в специальном регистре флагов (FLAGS). В данном случае флаг CF (carry flag) примет значение, равное единице (иногда говорят – флаг поднят). Рассматривая результат в знаковых числах, мы получили правильный ответ, поэтому соответствующий флаг OF (overflow flag) будет положен равным нулю (опущен).
· Пример 2.
Б/з. | Знак. | |
-124 |
В данном примере ошибка будет, наоборот, в случае со знаковой трактовкой складываемых чисел, поэтому флаги CF и OF принимают соответственно значения 0 и 1.
· Пример 3.
Б/з. | Знак. | |
–10 | ||
–119 | ||
+127 |
В данном случае результат будет ошибочен как при беззнаковой, так и при знаковой трактовке складываемых чисел. Содержимое флагов: CF = OF = 1. Легко придумать пример, когда результат сложения правильный как для знаковых, так и для беззнаковых чисел (сделайте это самостоятельно!).
Кроме формирования флагов CF и OF команда сложения целых чисел меняет и значения некоторых других флагов в регистре флагов FLAGS. Для нас будет важен флаг SF, в который заносится знаковый (крайний правый) бит результата, и флаг ZF, который устанавливается в 1, если результат равен нулю, в противном случае этот флаг устанавливается в 0.
Представление отрицательных чисел в дополнительном коде не очень удобно для программистов, однако, позволяет существенно упростить арифметико-логическое устройство. Заметим, например, что вычитание можно выполнять как сложение с дополнительным кодом числа.
Основная причина использования двух систем счисления для представления целых чисел заключается в том, что при использовании обеих систем счисления диапазон представимых целых чисел увеличивается в полтора раза. Это было весьма существенно для первых ЭВМ с их небольшим объёмом памяти.
Дата добавления: 2015-10-05; просмотров: 746;