Implementing min of 3 numbers in Mic-1 code I have the following algorithm to find a minimum of three input numbers:

min(a,b,c):
   x := a
   if b &lt; x then x := b
   if c &lt; x then x := c
   return x
end min(a,b,c)


I'm trying to implement a Mic-1 micro code following the algorithms above:

OP1, OP2, OP3 = any 16 bit 2s complement value

OPRES: 0
      .LOC 50
main: LODD OP1: push
      LODD OP2: push
      LODD OP3: push
      CALL min:
      INSP 2
      STOD OPRES
      HALT
min:  LODL 1; OP1
      SUBL 2; OP2 - OP1
      JPOS op1small
      SUBL 3; OP3 - OP1
      JPOS op1small
op1small: 
      LODL 1
      RETN ; OP1


I'm pretty new to Mic-1 and would like to get any input on this Mic-1 code above. Is there a better or shorter way I can find a min of three numbers in Mic-1?
Min... ish


  Is there a better or shorter way I can find a min of three numbers in Mic-1?


Maybe, but first you should be finding the min of three numbers because right now, that's not what is happening.

This is what your current assembly code looks like translated to a pseudo-code:

ac = OP1
ac -= OP2
if ac &gt; 0, return OP1
ac -= 3
if ac &gt; 0, return OP1
return OP1


Try following this through with some example numbers. Still don't understand where you are going wrong? Look at this example again with some mo

; OP1 = 3, OP2 = 2, OP3 = 1
ac = 3
ac -= 2 ; ac is now 1
; ac is &gt; 0, so jump passes and OP1 is returned when OP3 should be instead


See it now? This was probably overlooked due to the fact that you did not thoroughly test your code. It is important to test even the most extreme cases to make sure that your code is cleaned.

Now we need to re-write your code. First off, let's break down your code: instead of trying to find the min of just three numbers, why not try to find the min of two numbers? Then, this subroutine could be used in other min-based subroutines.

I think that the min subroutine would now look like this:

min2:
    LODL 1 ; ac = OP1
    SUBL 2 ; ac -= OP2
    JPOS min2_op2small ; if ac &gt; 0

    LODL 1
    RETN
op2small:
    LODL 2
    RETN


If you are having trouble understanding how this works, try plugging in some values in your head. Here is a run down of what it is doing


Store OP1 in the accumulator.
Subtract OP2 from the accumulator.
If the accumulator is negative, then return OP1.
If the accumulator is positive, then return OP2.


Now that we have this basic min subroutine, we can the subroutine for finding the min of 3 numbers.

Using our handy-dandy min2 sub, this new subroutine can simply use the min2 sub to determine what is the greater of the three values:


Find the min2 of OP1 and OP2
Compare the lesser one with OP3
Return the lesser one.


Your current code already follows this structure. However, as show above, it doesn't quite do what it seems.



Comments

You seem slightly confused about how this "architecture" works, judging by your comments. In particular, these ones:

  SUBL 2; OP2 - OP1
  ...
  SUBL 3; OP3 - OP1


No; you aren't subtracting 1st parameter from the 2nd and 3rd ones here. In reality, these two statements are the equivalent of


  \$(OP1-OP2)-OP3\$


Why is it like this and not how you have indicated it? Here is what your code is doing, minus the conditionals:


Load the accumulator with OP1
Subtract OP2 from the accumulator.
Subtract OP3 from the accumulator.


The accumulator is a register that is used to hold a single value that is often the result of arithmetic. More simple instruction sets (such as this one) force any arithmetic to be done with one of the operands being the accumulator.

See what the difference is? Your comments seemed to act as if there were no conditional whatsoever. More accurate comments would be:

SUBL 2; ac = OP1 - OP2
...
SUBL 3; ac = (OP1 - OP2) - OP3