Как я могу объединить два 32-битных регистра в 64-битный ответ? - PullRequest
1 голос
/ 18 ноября 2010

Я использую программу pcsim, которая, как мне кажется, использует MIPS. Я не уверен, поскольку я очень плохо знаком с языком ассемблера. Мне нужно умножить два 32-битных числа, используя только сложение и сдвиг, и хранить продукт в двух регистрах. Я получил его там, где он успешно умножит два числа, ЕСЛИ результат может быть сохранен в 32 битах. Проблема в том, что если число больше этого, я не могу понять, как объединить правую половину продукта с левой половиной. Левый половинный регистр должен содержать значения, начиная с 2 ^ 32 до конца. Если это не ясно, я могу попытаться объяснить больше. Есть ли какой-то простой способ, который я упускаю, чтобы выполнить это? Спасибо за любую помощь.

Ответы [ 2 ]

1 голос
/ 19 ноября 2010

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

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

Вот несколько примеров в виде фрагментов Си (их легко перевести на MIPS, если это то, что вы на самом деле используете). Я предполагаю, что вы работаете с 32-разрядными числами без знака и хотите получить 64-разрядные результаты без знака.

Логический сдвиг влево на 1 бит:

tmp = lo >> 31;  /* top bit of lo to bottom bit of tmp, rest of tmp is 0 */
lo <<= 1;
hi <<= 1;
hi |= tmp;

Логический сдвиг вправо на 1 бит:

tmp = hi << 31;  /* bottom bit of hi to top bit of tmp, rest of tmp is 0 */
hi >>= 1;
lo >>= 1;
lo |= tmp;

(фактически вы можете заменить 1 и 31 на n и (32 - n) для сдвига на некоторое другое количество бит)

64-разрядное дополнение:

result_lo = a_lo + b_lo;
result_hi = a_hi + b_hi;
if (result_lo < a_lo)
    result_hi++;

(см. здесь для более подробной информации об этом, со специальной ссылкой на MIPS).


Альтернативный подход - рассматривать каждый из ваших 32-битных входов как пару 16-битных «цифр»; умножение двух 16-битных чисел дает максимум 32-битный результат. Итак, основная идея такова:

0x12345678 * 0x23456789 =     0x5678 * 0x6789
                          + ((0x1234 * 0x6789) << 16)
                          + ((0x5678 * 0x2345) << 16)
                          + ((0x1234 * 0x2345) << 32)

(вам все равно понадобятся некоторые 64-битные дополнения).

0 голосов
/ 19 ноября 2010

Нет способа «объединить» две половины в один 32-битный регистр.Если вы хотите объединить две половины в одно 64-битное значение в памяти, вам нужно хранить обе половины помимо каждой другой в соответствии с порядком работы вашей машины.Если вы используете SPIM, похоже, он использует ту же самую задницу вашего хост-компьютера.

X86?Маленький порядковый номерХраните нижнюю половину первым.КПП?Большой порядокСначала сохраните верхнюю половину.

...