1

My program needs to accept 3 inputs and then check if they form a Pythagorean triple. I'm using the Little Man Computer to do this, and therefore I am using LMC assembly. If you want more info on the commands that can be used, or to download the simulator I'm using, here is the link

Here is the code I've written so far.

#Valid mnemonics are:
# HLT, ADD, SUB, STO, LDA,
# BR, BRZ, BRP, IN, OUT, DAT
# The first part of the program will sort a,b and c, so that they will always be in order from
# a,b,c                                  



        IN      #get first input
        STO c   
        IN      #get second input   
        STO b
        IN      #get third input
        STO a

        SUB b   #Test if a>b
        BRP swapAB
        BR next1

swapAB  LDA b   #Swaps a and b
        STO temp
        LDA a
        STO b
        LDA temp
        STO a   #continues on to next1

next1   LDA b   #Test if b>c
        SUB c
        BRP swapBC
        BR end  #All sorted

swapBC  LDA c   #Swaps b an c
        STO temp
        LDA b
        STO c
        LDA temp
        STO b
        BR next2

next2   LDA a   #tests new a>b
        SUB b
        BRP swapAB  


end     LDA a   #begin the process of squaring a
        STO total
        SUB one
        STO count
loop1   LDA total
        ADD a
        STO total
        LDA count
        SUB one
        STO count
        BRZ endsq1
        BR loop1

endsq1  LDA total
        STO d   #stores a*a in d
        OUT #for testing. Outputs a*a
        SUB total
        STO total   

         LDA b  #Begins squaring b
         STO total
         SUB one
         STO count
loop2    LDA total
         ADD b
         STO total
         LDA count
         SUB one
         STO count
         BRZ endsq2
         BR loop2   #end of squaring b

endsq2   LDA total
         STO e  #stores b*b in e
         OUT
         SUB total
         STO total

         LDA c  #begin squaring c
         STO total
         SUB one
         STO count
 loop3   LDA total
         ADD c
         STO total
         LDA count
         SUB one
         STO count
         BRZ endsq3
         BR loop3   #end squaring c

         endsq3 LDA total
         STO f  #stores c*c in f
         OUT
         SUB total
         STO total

         LDA d  #begin check a^2 + b^2 = c^2
         ADD e
         SUB f
         BRZ true
         LDA count
         OUT    #FALSE output 000
         HLT
true     LDA one    
         OUT    #TRUE output 001
         HLT

a        DAT
b        DAT
c        DAT
d        DAT
e        DAT
f        DAT
temp     DAT
total    DAT 000
one      DAT 001
count    DAT 000

The program will output 001 if a,b,c form a Pythagorean triple or 000 if not. However it also needs to output 002, if overflow occurs i.e. the inputs exceed the LMC 3 digit limit.

I know that the code works for checking if a,b,c are Pythagorean triples. However, I need some way of checking for overflow (LMC only accepts 3 digit values). To make this harder, there is no overflow flag on the LMC version I'm using. My thoughts are to check if c > 31, as anything above 31 will be greater than 1000 when squared, and to somehow check if a^2 + b^2 > 1000.

To further complicate this, the LMC only has 99 memory addresses to store both data and instructions, and I have only 5-6 left. Is there anyway I can simplify the above code to reduce the amount of memory the program instructions take up? I originally thought I could use one loop for the squaring process, but I'm not sure how I would then branch off to save the result in a different variable each time.

Any help would be greatly appreciated.

UPDATE: Here is the insertion sort lmc code that works

inloop  IN # get a number
        STO tmp
        SUB range #check input < 31 
        BRP error
        LDA tmp
        SUB c # bigger than the biggest so far?
        BRP storeC
        LDA b
        BRZ storeB # if empty, use b
        LDA tmp    # must use a
        STO a
        BR minus
storeB  LDA tmp
        STO b
        BR minus
storeC  LDA b
        BRZ fillB # if empty, use b
        BR fillA  # otherwise, use a
fillB   LDA c    
        STO b
        LDA tmp
        STO c
        BR minus
fillA   LDA c 
        STO a
        LDA tmp
        STO c
        BR minus   
minus   LDA incount
        SUB one
        BRZ next
        STO incount
        BR inloop
next    LDA a
        OUT
        LDA b
        OUT
        LDA c
        OUT
        HLT
error   LDA overflow
        OUT
        HLT

range   DAT 031
a   DAT 000
b   DAT 000
c   DAT 000
tmp DAT
overflow DAT 002
incount DAT 003
one DAT 001
JC2188
  • 337
  • 3
  • 17

1 Answers1

0

Once you know that the individual squares are valid, you can rearrange the equation to c^2 - a^2 - b^2 = 0. You can test for that equality while also testing for the negative flag which signals overflow.

To compact the code, you can indeed create a loop that reads and squares a number and also puts it in place. Since you are sorting the numbers anyway, you don't really care about the order they were entered. You can use insertion sort algorithm, making sure the 3 data locations are zero initialized.

Update: here is sample code showing a rough outline of the loop body:

        IN # get a number
        STO tmp
        # do range check here
        SUB c # bigger than the biggest so far?
        BRP storeC
store   LDA b
        BRZ storeB # if empty, use b
        LDA tmp    # must use a
        STO a
        BR next
storeB  LDA tmp
        STA b
        BR next
storeC  LDA c
        STO tmp2
        LDA tmp    # store new number
        STO c      # as biggest
        LDA tmp2   # insert previous biggest
        STO tmp
        BR store
next    # repeat until we got 3 numbers (use a counter)

Note I have optimized it a little more, since we only need to know which is the biggest number (that goes into c) but the relation of a and b doesn't matter. I hope this works, I haven't tested it.

Jester
  • 56,577
  • 4
  • 81
  • 125
  • Thanks. I'm still unsure about how to create the loop so that it outputs the result to a different memory address each time? – JC2188 Nov 04 '14 at 23:14
  • The point is, you have to insert the item in the appropriate place, that's how insertion sort works. – Jester Nov 04 '14 at 23:40
  • I understand what the insertion sort does, but I have no idea how I would implement it using LMC code. I've looked at some assembly code for insertion sort, but I don't know assembly, or how to work with individual registers, rather than the simplified "calculator" idea from the LMC – JC2188 Nov 05 '14 at 00:41
  • Thanks for the code. It doesn't work when you enter a sequence of numbers from smallest to largest, as the storeC routine overwrites a, without doing anything to b, so you end up with values in a and c, but not b. I've updated my question with the code that works, although I'm not sure if there is a more efficient way of doing it. – JC2188 Nov 05 '14 at 02:17
  • Ah, indeed there seems to be a problem with that case. – Jester Nov 05 '14 at 13:02
  • But that should be easy to fix, see update. At least I hope I got it right, now :) – Jester Nov 06 '14 at 00:12