我正在使用我认为使用 MIPS 的 pcsim 程序。我并不积极,因为我对汇编语言很陌生。我只需要使用 add 和 shift 将两个 32 位数字相乘并将乘积存储在两个寄存器中。如果结果可以存储在 32 位中,我已经将它成功地乘以两个数字。问题是,如果数字大于这个数字,我无法弄清楚如何将产品的右半部分与左半部分结合起来。左半部分寄存器应该保存从 2^32 开始的值。如果不清楚,我可以尝试解释更多。我忽略了一些简单的方法来实现这一点吗?谢谢你的帮助。
问问题
4179 次
2 回答
1
如果我理解正确的话,你会被困在你实际上需要做 64 位算术的地步,对吧?
如果您正在执行典型的移位和加法二进制长乘法,您可以从 32 位操作构建一些 64 位移位和加法原语,然后使用相同的方法。
以下是一些作为 C 片段的示例(如果您实际使用的是 MIPS,那么转换为 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;
(实际上,您可以用 and 替换and1
并移动其他位数)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 位添加)。
于 2010-11-18T22:42:00.513 回答
0
没有办法将这两部分“组合”成一个 32 位寄存器。如果要将两半合并为内存中的一个 64 位值,则需要根据机器的字节序将两半并排存储。如果您使用的是 SPIM,它似乎使用与您的主机相同的 enianness。
X86?小端。先存放下半部分。每次点击付费?大端。先存放上半部分。
于 2010-11-18T21:06:57.420 回答