Виды данных. Операции с числами и структура системы команд, страница 3

При сложении чисел со знаком: если знаки разные - переполнения быть не может.

Если знаки одинаковые, и знак результата...

Совпадает со знаками операндов         - переполнения нет
противоположен знаку операндов         - переполнение есть.

При действиях над числами со знаком переполнение происходит, если пересекаем границу разрыва 011..11 - 10..00. Для регистрации этих фактов в процессоре обычно делают два триггера (чаще всего они входят в состав регистра состояний). Содержимое этих триггеров называют битами признаков или флагами.

C (или cf -от CARRY - перенос) регистрирует при выполнении многих операций перенос/заем из старшего (знакового) разряда за границу разрядной сетки

V (или of от OVerFlow - переполнение) - регистрирует перенос/заем в старший (знаковый) разряд.

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

В некоторых процессорах используется арифметика «с насыщением» (saturation)/

Команды для действий с целыми числами

Далее описывается действие основных команд, имеющихся в большинстве процессоров, примеры мнемоник приводятся для системы команд i*86.

Сложение и вычитание

Обе операции трехоперандные: два слагаемых и результат. Формат команды может быть: 3-х операндным –
          2-х операндным – результат помещается на место одного из слагаемыых (так в I*86)
          1-операндным – второй операнд и сумма находятся в предопределенном месте (в регистре-аккумуляторе)
          нуль-операндным – оба операнда находятся в предопределенных местах (чаще всего это стек).

Будем, если не оговорено другое, использовать соглашения ассемблера Intel

          add   a, b                      a ß a + b   так принято в Intel – ассемблере, т.е. результат сложения помещается на место операнда a. Аналогично для вычитания :
          sub   a, b

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

Для действий умножения и деления это не так.

Глядя на двоичное представление целого числа, невозможно сказать, знаковое оно или беззнаковое.

При выполнении операции схемотехника процессора изменяет значения битов cf и of. Анализируя эти биты, можно узнать, не выходит ли результат сложения или вычитания за пределы представимого диапазона. (Как это сделать, узнаем позже).

Если не хватает разрядности, поддерживаемой АЛУ, то можно искусственно увеличить разрядность - хранить величины в нескольких машинных словах. Рассмотрим, как можно организовать сложение двух «длинных» операндов, используя «короткое» сложение.

+

an-1 an-2 …… a1 a0

 +cfß

bn-1 bn-2 …… b1 b0

+

A2n-1 a2n-2 …… an-1 an

+

B2n-1 b2n-2 …… bn-1 bn

cfß

B2n-1 b2n-2 …… bn-1 bn

bn-1 bn-2 …… b1 b0

Результат переноса при сложении младших частей регистрируется в флаге cf. Его значение надо учитывать при сложении старших частей.

Для учета при сложении значения флага переноса cf в систему команд добавляют команду сложения с переносом:      adc      a, b                (работает так: a ß a + b + cf)

Последовательность команд при выполнении сложения с двойной точностью может быть такой

          add   b0, a0                   ; b0 ß b0 + a0  (перенос в cf)
          adc   b1, a1                  ; b1 ß b1 + a1 + cf

В некоторых системах команд (например DEC16) команда adc однооперандная : a=a+cf  и тогда так:

          add   b0, a0                  ; b0 ß b0 + a0
          adc   b1
                        ; b1 ß b1 + cf
          add   b1, a1                 
; b1 ß b1 + a1                         //  Вопрос о тройной точности

Как перейти от представления с однарной точностью к представлению с двойной ? Для положительных чисел просто - старшее слово - нулевое.

Для отрицательных - операция расширения знака (Sign Extention). Ее действие состоит в заполнении старшего слова знаковыми битами младшего. В системе команд I*86 есть команды cbw преобразования 8 битà16 бит, cwd преобразования 16 бит à 32 бит и cdq.

Умножение и деление

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

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

В большинстве процессоров АЛУ устроено так, что соотношение разрядностей операндов и результата в командах умножения и деления следующее:

(n) * (n) = (2n),              (2n) / (n) = (n)q(n)r, т.е. разрядность произведения и делимого вдвое больше. Что делать с «длинным» результатом – проблема программиста.