Reputation:
I am using a Little Man Computer simulator program called visible virtual machine to learn the basics of coding in assembly language format. Currently I am trying to multiply any two numbers (x
& y
) but in an efficient way by grabbing the greatest number and adding to it how many times the lesser number is equal to. How can I swap the numbers so it takes the greatest number and adds how many times the lesser number is equal to?
For example
The input can be either:
5 * 12
or 12 * 5
Efficient calculation:
12 + 12 + 12 + 12 +12 = 60
Not efficient:
5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 = 60
Code:
IN
STO 99
IN
STO 98
STO 96
LDA 99
SUB 97
STO 99
LDA 96
ADD 98
BRP 07
LDA 96
OUT 96
*95
DAT 001
HLT
Upvotes: 0
Views: 6252
Reputation: 9211
Looking at the command listing, it looks like you could achieve this by subtracting the first input from the second and then use conditional branching to see which is the greater. Something like this:
INP // Get input into accumulator
BRZ QUIT // If zero, we're finished
STA A // Accumulator to A
INP // Get input into accumulator
BRZ QUIT // If zero, we're finished
STA B // Accumulator to B
SUB A // Subtract A from accumulator (B)
BRP LOOP // Jump to LOOP if B > A already, otherwise swap
LDA A // Put A into accumulator
STA TEMP // Accumulator to TEMP
LDA B // Put B into accumulator
STA A // Overwrite A with B
LDA TEMP // Put TEMP (A) into accumulator
STA B // Overwrite B with A: now B > A
LOOP LDA AB // Put result into accumulator (starts off as zero)
ADD B // Add larger input to accumulator
STA AB // Update result
LDA A // Put loop counter (A) into accumulator
SUB ONE // Decrement
STA A // Update loop counter
BRZ DONE // Jump to DONE if loop counter is zero
BRP LOOP // Jump to LOOP if loop counter is positive
DONE LDA AB // Put result into accumulator
QUIT OUT // Output
HLT // Finish
ONE DAT 1 // ONE = 1
A DAT // First input
B DAT // Second input
AB DAT // A * B
TEMP DAT // Temporary (needed for swap)
Note that this is completely untested, so it's highly possible that it contains a bug! However, I've commented the source, so you can see the idea.
EDIT Turns out there are no bugs -- not bad for a stab in the dark ;) Anyway, the following is the slightly modified syntax that runs on the Java-based simulator mentioned in the comments:
INP // Get input into accumulator
BRZ :QUIT // If zero, we're finished
STA :A // Accumulator to A
INP // Get input into accumulator
BRZ :QUIT // If zero, we're finished
STA :B // Accumulator to B
SUB :A // Subtract A from accumulator (B)
BRP :LOOP // Jump to LOOP if B > A already, otherwise swap
LDA :A // Put A into accumulator
STA :TEMP // Accumulator to TEMP
LDA :B // Put B into accumulator
STA :A // Overwrite A with B
LDA :TEMP // Put TEMP (A) into accumulator
STA :B // Overwrite B with A: now B > A
LOOP: LDA :AB // Put result into accumulator (starts off as zero)
ADD :B // Add larger input to accumulator
STA :AB // Update result
LDA :A // Put loop counter (A) into accumulator
SUB :ONE // Decrement
STA :A // Update loop counter
BRZ :DONE // Jump to DONE if loop counter is zero
BRP :LOOP // Jump to LOOP if loop counter is positive
DONE: LDA :AB // Put result into accumulator
QUIT: OUT // Output
HLT // Finish
ONE: 1 // ONE = 1
A: 0 // First input
B: 0 // Second input
AB: 0 // A * B
TEMP: 0 // Temporary (needed for swap)
Upvotes: 1