Skip to main content
Engineering LibreTexts

3.4: Multiplication in MIPS Assembly

  • Page ID
    27109
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)

    Multiplication and division are more complicated than addition and subtraction, and require the use of two new, special purpose registers, the hi and lo registers. The hi and lo registers are not included in the 32 general purpose registers which have been used up to this point, and so are not directly under programmer control. These sections on multiplication and addition will look at the requirements of the multiplication and division operations that make them necessary.

    Multiplication is more complicated than addition because the result of a multiplication can require up to twice as many digits as the input values. To see this, consider multiplication in base 10. In base 10, 9x9=81 (2 one digit numbers yield a two digit number), and 99x99=9801 (2 two digit numbers yield a 4 digit number). As this illustrates, the results of a multiplication require up to twice as many digits as in the original numbers being multiplied. This same principal applies in binary. When two 32-bit numbers are multiplied, the result requires a 64-bit space to store the results.

    Since multiplication of two 32-bit numbers requires 64-bits, two 32-bit registers are required. All computers require two registers to store the result of a multiplication, though the actual implementation of those two registers is different. It MIPS, the hi and lo registers are used, with the hi register being used to store the 32 bit larger part of the multiplication, and the lo register being used to the store the 32 bit smaller part of the multiplication.

    In MIPS, all integer values must be 32 bits. So if there is a valid answer, it must be contained in the lower 32 bits of the answer. Thus to implement multiplication in MIPS, the two numbers must be multiplied using the mult operator, and the valid result moved from the lo register. This is shown in the following code fragment which multiplies the value in $t1 by the value in $t2, and stores the result in $t0.

    mult $t1, $t2
    mflo $t0
    

    However what happens if the result of the multiplication is too big to be stored in a single 32-bit register? Again consider base 10 arithmetic. 3*2=06, and the larger part of the answer is 0. However 3*6=18, and the larger part of the answer is non-zero. This is true of MIPS multiplication as well. When two positive numbers are multiplied, if the hi register contains nothing but 0's then there is no overflow, as the multiplication did not result in any value in the larger part of the result. If the hi register contains any values of 1, then the result of the multiplication did have an overflow, as part of the result is contained in the larger part of the result. This is shown in the two examples, 3*2=06, and 3*6=18, below.

    Screen Shot 2020-06-29 at 1.32.53 PM.png

    So a simple check for overflow when two positive numbers are multiplied to see if the hi register is all 0's: if it is all 0's the result did not overflow, otherwise the result did overflow.

    This is fine for two positive or two negative number, but what if the input values are mixed? For example, 2*(-3) = -6, and 2*(-8) = -18. To understand what would happen, these problems will be implemented using 4-bit registers.

    Remember that 4-bit registers can contain integer values from -8..7. So the multiplication of 2*(- 3) and 2*(-6) in 4-bits with an 8-bit result is shown below:

    Screen Shot 2020-06-29 at 1.34.13 PM.png

    In the first example, the high 4-bits are 1111, which is the extension of the sign for -6. This says that the example did not overflow. In the second example, the high 4-bits are 1110. Since all 4 bits are not 1, they cannot be the sign extension of a negative number, and the answer did overflow. So an overly simplistic view might say that if the high order bits are all 0's or all 1's, there is no overflow. While this is a necessary condition to check for overflow, it is not sufficient. To see this, consider the result of 6*(-2).

    Screen Shot 2020-06-29 at 1.35.11 PM.png

    Once again, the high 4-bits are 1111, so it looks like there is not an overflow. But the difficulty here is that the low 4 bits show a positive number, so 1111 indicates that the lowest 1 (the one underlined), is really part of the multiplication result, and not an extension of the sign. This result does show overflow. So to show overflow in a the result contained in the hi register must match all 0's or all 1's, and must match the high order (sign) bit of the lo register.

    Now that the fundamentals of integer multiplication have been covered, there are five MIPS multiplication operators which will be looked at. They are:

    • mult operator, which multiplies the values of Rs and Rt and saves it in the lo and hi registers. The format and meaning of this operator is:

      format:

      mult Rs, Rt

      meaning:

      [hi,lo] <- Rs * Rt

    • mflo operator, which moves the value from the hi register into the Rd register. The format and meaning of this operator is:

      format:

      mflo Rd

      meaning:

      Rd <- lo

    • mfhi operator, which moves the value from the hi register into the Rd register. The format and meaning of this operator is:

      format:

      mfhi Rd

      meaning:

      Rd <- hi

    • mult operator, which multiples the values in Rs and Rt, and stores them in Rd. The format and meaning of this operator is:

      format:

      mult Rd, Rs, Rt

      meaning:

      Rd <- Rs * Rt

    • mulo pseudo operator, which multiples the values in Rs and Rt, and stores them in Rd, checking for overflow. If overflow occurs an exception is raised, and the program is halted with an error. The format and meaning of this operator is:

      format:

      mulo Rd, Rs, Rt

      meaning:

      Rd <- Rs * Rt

    • Note that both the mult and mulo operators have an immediate pseudo operator implementation. The format, meaning, and translation of the pseudo operators is as follows:

      format:

      mult Rd, Rs, Immediate

      meaning:

      Rd <- Rs * Immediate

      translation:

      addi $Rt, $zero, Immediate

      mult Rd, Rs, Rt

      format:

      mulo Rd, Rs, Immediate

      meaning:

      Rd <- Rs * Immediate

      translation:

      addi $Rt, $zero, Immediate

      mulo Rd, Rs, Rt


    3.4: Multiplication in MIPS Assembly is shared under a CC BY 4.0 license and was authored, remixed, and/or curated by Charles W. Kann III.

    • Was this article helpful?