MIPS Calculator implementing division with subtraction and addition, avoiding DIV and REM instructions

StackOverflow https://stackoverflow.com/questions/22155719

  •  19-10-2022
  •  | 
  •  

Question

I'm working on the classic MIPS calculator example, but am attempting to change the divis (division) routine below to use only addition and subtraction instead of MIPS div operation (similar to what I have done with multiplication). This is probably very easy to do, but I am new to MIPS and every attempt I have made so far hasn't worked. Help?

I'm using qtspim as my simulator

What I have so far for division:

    start_divis:    
        add $t1, $zero, $s0   #make copy of first integer value in $s0
        add $t2, $zero, $s1   #make copy of second integer value in $s1
        add $t0, $zero, $zero #make $t0 the temporary variable to act as a counter

    div_loop:
        slt $t3, $t2, $t1        #checks if $t1 > $t2
        sub $t1, $t1, $t2        #subtract $t2 from $t1
        addi $t0, 1              #add one to counter
        bne $t3, $zero, div_loop #if first number < second number, loop

    end_divis:
        move $s5, $t0      #store answer  
        move $s6, $t1      #store remainder
        la  $a0, divi_s    #get division symbol
        move $s7, $a0      #move it to $s7

        j div_ans          #jump to div_ans
Was it helpful?

Solution

If you can get away with integer division (i.e. 1/2 = 0) consider the following pseudo code:

function multiply(a, b):

    sum := 0
    for i = 0 to b:
        sum := sum + a

    return sum

function divide(a,b):

    count := 0

    while a ≥ b:
        a := a - b
        count := count + 1

    return count

There are a few errors with what you've written:

Firstly the line

slt $t3, $t2, $t1 #checks if $t1 > $t2

is incorrect. The correct way to negate > is with ≤. This means the line should be changed to:

sle $t3, $t2, $t1 #checks if $t1 > $t2

Next you have the condition of your loop at the top but the actual branch that uses it at the bottom. You should be aware that a while loop always checks the condition at the top.

Consider:

div_loop:
    sle $t3, $t2, $t1        #checks if $t1 > $t2
    beq $t3, $zero, end_divis #if first number < second number, break

    sub $t1, $t1, $t2        #subtract $t2 from $t1
    addi $t0, 1              #add one to counter
    j div_loop               #loop
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top