0

So I am trying to find the greatest common denominator between 3 numbers. I think that my logic is pretty sound on how to do this and I am currently not getting the correct output.

li $s0, 1 

whileloop:
bgt $s0, $t0, exit 
bgt $s0, $t1, exit 
bgt $s0, $t2, exit 
    IF1:
    div $s0, $t0 
    mfhi $s1 
    bne $s1, $zero, else  


  IF2: 
    div $s0, $t1
    mfhi $s2 
    bne $s2, $zero, else  

   IF3:
   div $s0, $t2 
   mfhi $s3 
   bne $s3, $zero, else 
   sw $s0, 4($s4)
   j else 

    else: 
    addi $s0, $s0, 1 
    j whileloop 


exit: 

    la $a0, answer 
    syscall 

    move $a0, $s4 
    li $v0, 1 
    syscall 

    li $v0, 10 
    syscall 

The three numbers are user inputted into $t0, $t1, and $t2.

Michael
  • 57,169
  • 9
  • 80
  • 125
Rob. B
  • 19
  • 5

1 Answers1

2

Your logic is sound but your div instructions are incorrect. Reverse the arguments on all three. For example, you're doing s1 = s0 % t0 and you want s1 = t0 % s0

WARNING: You can't do multiply/divide within two instructions after mflo/mfhi, so you need to add a nop here and there. See http://chortle.ccsu.edu/assemblytutorial/Chapter-14/ass14_5.html In particular, your div's at if2/if3 violate this in the fall through case.

Personally, I'd fix this by changing it after the mfhi rather than before the div. IMO, that's cleaner because the restriction comes from mfhi [not div], so associate the compensation with it. And, for the sake of regularity, I'd put it on all three mfhi's even though one doesn't actually need it.

Change:

    mfhi ...
    bne ...

ifX:
    div ...

Into:

    mfhi ...
    nop
    bne ...

ifX:
    div ...

Just for fun, here's your program translated back into C:

int
gcd(int t0,int t1,int t2)
{
    int s0;
    int s1;
    int s2;
    int s3;
    int rtn;

    rtn = -1;

    s0 = 1;

Lloop:
    if (s0 > t0) goto Lexit;
    if (s0 > t1) goto Lexit;
    if (s0 > t2) goto Lexit;

Lif1:
#if 0
    s1 = s0 % t0;
#else
    s1 = t0 % s0;
#endif
    if (s1 != 0) goto Lelse;

Lif2:
#if 0
    s2 = s0 % t1;
#else
    s2 = t1 % s0;
#endif
    if (s2 != 0) goto Lelse;

Lif3:
#if 0
    s3 = s0 % t2;
#else
    s3 = t2 % s0;
#endif
    rtn = s0;
    if (s3 != 0) goto Lelse;

Lelse:
    s0 += 1;
    goto Lloop;

Lexit:
    return rtn;
}
Craig Estey
  • 30,627
  • 4
  • 24
  • 48