开发者

How can I comine two 32-bit registers into a 64-bit answer?

I am using the pcsim program which I believe uses MIPS. I'm not positive as I am very new to assembly language. I need to multiply two 32-bit numbers using only add and shift and store the product in two registers. I have gotten it to where it will successfully multiply two numbers IF the result can be stored in 32 bits. The problem is that if the number is larger than that, I can't figure out how to combine the right half of the product with the left half. The left half reg开发者_JAVA百科ister should hold values starting at 2^32 all the way up. If this isn't clear I can try to explain more. Is there some easy way I am overlooking to accomplish this? Thanks for any help.


If I've understood correctly, you're stuck at the point where you actually have a need to do 64-bit arithmetic, right?

If you're doing a typical shift-and-add binary long multiplication, you could build some 64-bit shift and addition primitives from 32-bit operations, then use the same method.

Here are some examples as C fragments (should be trivial to translate to MIPS, if that's what you're actually using). I'm assuming that you're working with unsigned 32-bit numbers and want unsigned 64-bit results.

Logical shift left 1 bit:

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

Logical shift right 1 bit:

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

(in fact you can replace the 1 and 31 with n and (32 - n) to shift by some other number of bits)

64-bit addition:

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

(see here for more detail about that, with specific reference to MIPS).


An alternative approach is to treat each of your 32-bit inputs as a pair of 16-bit "digits"; multiplying two 16-bit numbers gives at most a 32-bit result. So the basic idea is like this:

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

(you'll still need some 64-bit additions).


There is no way of "combining" the two halves into one 32-bit register. If you want to combine the two halves into one 64-bit value in memory, you need to store both halves besides eachother according to the endianess of your machine. If you are using SPIM, it appears it uses teh same enianness ass your host computer.

X86? Small endian. Store the lower half first. PPC? Big endian. Store the upper half first.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜