Двойное точное целочисленное вычитание с 32-разрядными регистрами (MIPS)

StackOverflow https://stackoverflow.com/questions/3940524

Вопрос

Я изучаю компьютерную арифметику. Книга, которую я использую (Паттерсон и Хеннесси) перечисляет следующий вопрос.

Написать MIPS-код для проведения двойного точного целочисленного вычитания для 64-битных данных. Предположим, что первый операнд будет в регистрах $ T4 (HI) и $ T5 (LO), второй в $ T6 (HI) и $ T7 (LO).

Мое решение ответа

sub  $t3, $t5, $t7   # Subtract lo parts of operands. t3 = t5 - t7
sltu $t2, $t5, $t7   # If the lo part of the 1st operand is less than the 2nd,
                     #   it means a borrow must be made from the hi part
add  $t6, $t6, $t2   # Simulate the borrow of the msb-of-low from lsb-of-high
sub  $t2, $t4, $t6   # Subtract the hi's. t2 = t4 - t6

Однако автор, заданные решения для этой проблемы, как показано ниже

Для подписанных целых чисел двойной точности,

subu $t3, $t5, $t7   
sltu $t2, $t5, $t7  
add  $t6, $t6, $t2
sub  $t2, $t4, $t6

Для беззначных целых чисел двойной точности,

subu $t3, $t5, $t7   
sltu $t2, $t5, $t7  
addu $t6, $t6, $t2
subu $t2, $t4, $t6

Мое понимание разницы в работе sub/add а также subu/addu это то, что переполнение - исключение генерируется в sub/add И не в subu/addu. Отказ Обе sub/add а также subu/addu Вычтете / добавить биты операндов, и интерпретация подписания операндов или без знака не имеет значения в отличие в отличие от slt а также sltu инструкции.

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

вопрос 2
Предполагая, что мой вышеуказанный вывод прав, почему обнаружение переполнения отключено для авторских решений в случае вычитания беззнаковой двойной точности с использованием addu а также subu?

Это было полезно?

Решение

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

Например, рассмотрите 8-битные последовательности (MIPS имеет 32-разрядные регистры, но для моих примеров для моих примеров для моих примеров можно проще 8 битов). Предположим, что интерпретация без знака: 8-битная последовательность представляет собой числовое значение от 0 до 255 (включено). Если я добавлю 10010011 (числовое значение 147) до 01110110 (числовое значение 118), то я получаю 00001001 (числовое значение 9). 9 не равен 147 + 118. Я получаю этот результат, потому что математическое значение составляет 265, что не может соответствовать 8 битам. Результат добавления потребовал бы 9 бит, но верхний девятый бит был сброшен.

Теперь представьте тот же пример с подписанный Интерпретация. 10010011 теперь имеет численное значение -109. 01110110 Все еще имеет числовое значение 118, а полученный результат (00001001) имеет значение 9. Математическая сумма -109 и 118 составляет 9, поэтому нет переполнения.

Это означает, что понятие переполнения зависит от того, как вы интерпретируете значения. Механика добавления одинаковы для подписанных, так и для подписанных интерпретаций (для той же входных последовательностей битов, вы получаете ту же выходную битную последовательность - это вся точка использования дополнения двух отрицательных значений), но обработка переполнения.

Архитектура MIPS обеспечивает средство для запуска исключений на переполнении. Концептуально, есть три Возможные операции добавления на 32-разрядные слова:

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

MIPS реализует первые два вида дополнений, с, соответственно, addu а также add Опкоды. В документациях MIPS они называются соответственно, беззначный а также подписал арифметику. Отказ Нет контрольного кода для повышения исключений на неподвижных переполнении. На практике C компиляторы используют только addu, но они могли бы использовать add Для подписанных типов (это разрешено стандартом C, но сломало бы ужасное много существующего кода). Компиляторы ADA используют add потому что ADA делает переполнение, проверку обязательным.

Что, как говорится...

Паттерсон и Хеннесси хотят реализовать подписанную и неподписанную арифметику на 64-битных целых числах. Для беззнаковой арифметики они не хотят никакого исключения, поэтому они используют addu а также subu. Отказ Для подписанной арифметики, они хотят, чтобы исключение произошло, когда математический результат не соответствует 64-битный последовательность с подписанной интерпретацией. Они не хотят поднимать исключение из-за некоторой ложного преодоления условий при обработке низких 32-битных половинок. Вот почему они используют subu для низких частей.

Ваше решение не так, потому что он может поднять исключение, где он не должен. Предположим, что вы хотите вычитать 2000000000 (два миллиарда) от -2000000000 (минус два миллиарда). Математический результат составляет 4000000000 (четыре миллиарда). Два операнда и результат, безусловно, вписываются в 64 бита (представимый ассортимент - 9223372036854775808 по 9223372036854775807). Следовательно, для 64-битной подписанной арифметики нет переполнения: не должно быть никакого исключения. Однако в этой ситуации ваш первый sub будет сообщать о переполнении. Это sub Работает с 32-битными значениями и подписано 32-битный арифметика. Его операнды будут 0111011100110101100101000000000000 и 10001000110000000000 и 100010001100101001101100000000000000. Обратите внимание, что эти значения соответствуют 32 битам: 32-битная подписанная интерпретация этих значений соответственно, плюс и минус два миллиарда. Однако результат вычитания - четыре миллиарда, и он не соответствует 32 битам (в качестве подписанного номера). Таким образом, ваш sub поднимает исключение.

Как правило, обнаружение переполнения состоит в том, чтобы делать вещи, которые зависят от интерпретации подписания, которые влияют на обработку наиболее значимого бита. Для большой целочисленной арифметики все слова, кроме наиболее значимых, должны рассматриваться как без знаки, следовательно, addu/subu где угодно. В качестве первого шага все легче понимать, если вы сначала концентрируетесь на неподписанной арифметике, без исключения (тогда вы просто используете addu а также subu, а также никогда add или sub).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top