Search code examples
javaassemblymipsmultiplication

Multiplication using add and shift: translating from Java to MIPS


I have to write in MIPS a program that multiplies two number using the add and shift method. After trying many many times, I got somehow a program that I see to should be working, but its not, then I wrote it in Java and the code worked in Java. Then I tried to convert it from Java to MIPS (usually its easier for me to translate to low level language from a code in high level language), and after translating it, still its not working. Here is the code I wrote, and please if anybody detects anything wrong with them or knows how to fix them please do tell me.

Thanks,

In Java:

static int prod = 0;

public static int mult (int mcand, int mier)
{
    while (mier != 0)
    {
        int rem = mier % 2;

        if (rem != 0)
        {
            prod += mcand;
        }

        mcand = mcand << 1;
        mier = mier >> 1;
    }

    return prod;
}

In MIPS:

# A program that multiplies two integers using the add and shift method

.data # Data declaration section

.text

main: # Start of code section

    li $s0, 72 # the multiplicand
    li $t0, 72 # the multiplicand in a temporary register
    li $s1, 4 # the multiplier
    li $t1, 4 # the multiplier in a temporary register
    li $s2, 0 # the product
    li $s3, 2 # the number 2 in a register for dividing by 2 always for checking if even or odd

LOOP: # first we check if the multiplier is zero or not

    beq $t1, $zero, END

    div $t1, $s3
    mfhi $t3 # remainder is now in register $t3

    beq $t3, $zero, CONTINUE # if the current digit is 0, then no need to add just go the shifting part

    add $s2, $s2, $t0 # the adding of the multiplicand to the product

CONTINUE: # to do the shifting after either adding or not the multiplicand to the product
    sll $t0, $t0, 1
    srl $t0, $t0, 1

    j LOOP # to jump back to the start of the loop

END:    
    add $a0, $a0, $s2
    li $v0, 1
    syscall

# END OF PROGRAM


Solution

  • Aside from @Joop Eggen's correction, you have to take into account whether delay branching takes into place or not. If the MIPS you are using has delay branching you should modify your program accordingly. The simplest way is to add a nop instruction after your jumps/branches (after the two beq and after j).

    Besides that, at the end of your code you are adding the result ($s2) to $a0 instead of moving it there.

    So, to summarize:

    • take into account delay branching, i.e. add nop after beq's and j
    • change srl $t0, $t0, 1 to srl $t1, $t1, 1
    • change add $a0, $a0, $s2 to add $a0, $0, $s2