title: MIPS 32-bit unsigned multiplication without using mult or div
body: <p>I have been working on a program does multiplication of two 32-bit unsigned integers without using the MIPS mult(multu) or div(divu) commands.
  I want the output to look just like how the multu function would, as a 64-bit high word/low word combo.
  I have been using a model where the multiplier is the right hand side of the product as so:</p>
  
  <pre><code>for (i=0; i&lt;32; i++)
  {
     if LSB(multiplier)==1
     {
         LH product += multiplicand;
     }
     right shift product-multiplier 1;
  }
  </code></pre>
  
  <p>Currently in my code I am unsure if I am taking care of the possible carry-out bit from the 32-bit addition properly.</p>
  
  <p>I am currently getting an output of "0 0" no matter what integer values I choose to operate on.</p>
  
  <p>In my code I am calling the right most bit the LSB(low word), left most the MSB(high word).</p>
  
  <p>My code:</p>
  
  <pre><code>.data
  
      promptStart:    .asciiz "This prrogram does AxB without using mult or div"
             getA:    .asciiz "Please enter the first number(multiplicand): "
             getB:    .asciiz "Please enter the second number(multiplier): "
  
            space:    .asciiz " "
  
           result:    .asciiz "The product, using my program is: "
           mipMult:   .asciiz "The product, using MIPs multu is: "
  
         endLine: .asciiz "\n"
  
  .text
  
  main:
      #"welcome" screen
      li  $v0,4           # code for print_string
      la  $a0,promptStart     # point $a0 to prompt string
      syscall             # print the prompt
  
  
      li  $v0,4           # code for print_string
      la  $a0,endLine     # point $a0 to prompt string
      syscall             # print the prompt
  
      #prompt for multiplicand
      li  $v0,4           # code for print_string
      la  $a0,getA        # point $a0 to prompt string
      syscall             # print the prompt
  
      #acquire multiplicand
      li  $v0,5           # code for read_int
      syscall             # get an int from user --&gt; returned in $v0
      move    $s0,$v0         # move the resulting int to $s0
  
      move    $s4,$s0         #copy of multiplicand to use in multu
  
      #prompt for multiplier
      li  $v0,4           # code for print_string
      la  $a0,getB        # point $a0 to prompt string
      syscall             # print the prompt
  
      #acquire multiplier
      li  $v0,5           # code for read_int
      syscall             # get an int from user --&gt; returned in $v0
      move    $s1,$v0         # move the resulting int to $s0
  
      move    $s5,$s1         #copy of multiplier to use in multu 
  
      jal MyMult
      j   print
  
  MyMult:
  
      #$s2 -&gt; lw product, $s1 -&gt; hw multiplier, $s0 -&gt; multiplicand
  
      beq $s1, $0, done       # if multiplier=0--&gt; mult gives 0
      beq $s0, $0, done
  
      move    $t0, $0         #initialize 'counter'= 31
      add $t0, $t0, 31
  
      move    $s2, $0         #initialize product = 0
  
      loopOut:
          beq $t0, $0, done   #loop check
  
          andi    $t1, $s1, 1 #Stores LSB(MSB?) of $s1 in $t1
          bne $t1, $0, loopIn #check if LSB is equal to 1
          srl $s1, $s1, 1
          srl $s2, $s2, 1 #right shift product &amp; multiplier
  
          add $t0, $t0,-1 # counter = counter -1
          j   loopOut
  
      loopIn:
          addu    $s2, $s2, $s0   #Lw product($s2/$s1)+= multiplicand($s0)
          sltu    $t2, $s2, $s0   #catch carry-out(0 or 1) and stores in $t2      
  
          srl $s1, $s1, 1
          srl $s2, $s2, 1 #right shift pro-plier..how to save LSB of $s2?
  
          #add carry-out $t2 to LSB of product $s2
          addu    $s2, $s2, $t0   #Is this right?
  
          addu    $t0, $t0,-1 # counter = counter -1
          j   loopOut
  
      done:
          jr $ra
  
  print:
      # print result string
      li  $v0,4           # code for print_string
      la  $a0,result      # point $a0 to string
      syscall             # print the result string
  
      # print out the result
      li  $v0,1           # code for print_int
      move    $a0,$s2         # put result in $a0
      syscall             # print out result
  
      li  $v0,4           # code for print_string
      la  $a0,space       # point $a0 to string
      syscall             # print the result string
  
      li  $v0,1           # code for print_int
      move    $a0,$s1         # put result in $a0
      syscall             # print out result
  
  
      # print the line feed
      li  $v0,4           # code for print_string
      la  $a0,endLine     # point $a0 to string
      syscall             # print the linefeed
  
  doMult:
  #Do same computation using Mult
      multu   $s4, $s5
      mfhi    $t0
      mflo    $t1
  
      li  $v0,4           # code for print_string
      la  $a0,mipMult     # point $a0 to string
      syscall 
  
      # print out the result
      li  $v0,1           # code for print_int
      move    $a0,$t0         # put high in $a0
      syscall             # print out result
  
      li  $v0,4           # code for print_string
      la  $a0,space       # point $a0 to string
      syscall             # print the result string
  
      # print out the result
      li  $v0,1           # code for print_int
      move    $a0,$t1         # put low in $a0
      syscall             # print out result
  
      # print the line feed
      li  $v0,4           # code for print_string
      la  $a0,endLine     # point $a0 to string
      syscall             # print the linefeed
  
      # All done, thank you!
      li  $v0,10          # code for exit
      syscall             # exit program
  </code></pre>