- #1
Enharmonics
- 29
- 2
Homework Statement
So basically, I have to implement the algorithm given in the relevant equations section.
Homework Equations
The Attempt at a Solution
First and foremost, my code. Some bits that weren't directly relevant to the problem I'm having were removed for readability's sake. The RightShift subroutine implements a logical shift right. Print subroutine just prints the contents of R0 onto the console in binary form.
Code:
.ORIG x3000
; Calculate AB = A x B
LEA R6, ARGS
LD R0, B
STR R0, R6, #0 ; Store B into Multiplier address of ARGS
JSR PRINT
LD R0, A
STR R0, R6, #1 ; Store A into Multiplicand address of ARGS
JSR PRINT
LEA R0, AB ; R0 <- starting address of AB
STR R0, R6, #2 ; Store starting address of AB into Product word of ARGS
JSR XMULT
; DID WE LOAD THE PRODUCT PROPERLY?
; THIS SHOULD PRINT THE LEAST SIGNIFICANT BITS OF PRODUCT
LDR R0, R0, #0
JSR PRINT
; THIS SHOULD PRINT THE MOST SIGNIFICANT BITS OF PRODUCT
LEA R0, AB
ADD R0, R0, #1
LDR R0, R0, #0
JSR PRINT
; Calculate XY = X * Y TRAP x25
; Test Data
A .FILL x0010
B .FILL x00AB
X .FILL x1234
Y .FILL xABCD
AB .BLKW 2
XY .BLKW 2
; Argument List
ARGS .BLKW 1 ;Multiplier (value)
.BLKW 1 ;Multiplicand (value)
.BLKW 1 ;Product (address);**********************************************************
XMULT ;Extended Multiplication
;Arguments located by R6
; multiplier (value)
; multiplicand (value)
; product (address)
ST R7, XMU7 ;Save Registers
ST R0, XMU0 ; TEMP register (for storing temp results and passing to RightShift subroutine)
ST R1, XMU1 ; Will store MPR (Multiplier)
ST R2, XMU2 ; Will store MND (Multiplicand)
ST R3, XMU3 ; Will store ACC (Accumulator)
ST R4, XMU4 ; Will serve as a COUNTER for loop
ST R5, XMU5 ; Will store BITMASK for testing
ST R6, XMU6 ; Argument list LDR R1, R6, #0 ; Store MPR into R1 (Multiplier is first item in the argument list pointed to by R6)
LDR R2, R6, #1 ; Store MND into R2 (Multiplicand is second item)
AND R3, R3, #0 ; ACC <- 0
LD R4, COUNTER ; Set counter
LD R5, BITMASK ; Set R5 to 0000 0000 0000 0001, the bitmask needed to test MPR[0]
; Counter and operands ready - now we can start the loop
MULOOP ; MUltiplication LOOP
AND R0, R5, R1 ; Test MPR[0]
BRz ELSE ; Branch if MPR[0] isn't set
ADD R3, R3, R2 ; ACC <- ACC + MND
ELSE
AND R0, R0, #0 ; Clear R0
ADD R0, R3, #0 ; R0 <- ACC
JSR SHIFT ; ShiftRight(ACC)
ADD R3, R0, #0 ; R3 <- Right-shifted ACC
ADD R0, R1, #0 ; R0 <- MPR
JSR SHIFT ; ShiftRight(MPR)
ADD R1, R0, #0 ; R1 <- Right-shifted MPR
ADD R4, R4, #-1 ; Decrement Counter
BRp MULOOP ; If Counter > 0, branch to beginning of loop
MULOOPEND ; MUltiplication LOOP ends here
; Write results to memory addresses (OUT-parameter segment)
LDR R0, R6, #2 ; R0 <- Product(address), least significant digit
STR R1, R0, #0 ; Right-shifted MPR goes in the lower address word
STR R3, R0, #1 ; Right-shifted ACC goes in the higher address word
LD R7, XMU7 ; Restore Registers
LD R0, XMU0
LD R1, XMU1
LD R2, XMU2
LD R3, XMU3
LD R4, XMU4
LD R5, XMU5
LD R6, XMU6
RET
XMU0 .BLKW 1
XMU1 .BLKW 1
XMU2 .BLKW 1
XMU3 .BLKW 1
XMU4 .BLKW 1
XMU5 .BLKW 1
XMU6 .BLKW 1
XMU7 .BLKW 1
; Data
COUNTER .FILL x0008
BITMASK .FILL x0001
;*********************************************************
The part that's giving me problems is in the MUltiplication LOOP (MULOOP in the code). A little perspective: I'm trying to test my code on the first bit multiplication given in the code, namely, I'm calculating
AB = A x B
where A = x0010 = b0000 0000 0001 0000
and B = x00AB = b0000 0000 1010 1011
To illustrate my problem, here's what happens when I execute the program:
Ignore the characters - those are there because the print function I used was borrowed from some other code I wrote that was supposed to print the char representations of bits.
Notice the first two bit values, 0000 0000 1010 1011 and 0000 0000 0001 0000. These correspond to the values A and B, which in decimal are 171 and 16, respectively.
The last two bit values, 0000 0000 0000 0000 and 0000 0000 0000 0000 1010, correspond to the right shifted MPR and ACC values that are supposed to represent the product of the two numbers.
Now, according to some bit multiplication calculators I've consulted, the product of x0010 and x00AB should be xAB0 = b1010 1011 0000
So basically, once the loop has fully iterated and the right-shifted ACC and MPR values are stored into their respective memory addresses, ACC contains a value that could possibly be part of the right answer (x000A), while MPR is totally empty (x0000).
For the answer to be correct as it is, MPR should contain xB000 = b1011 0000 0000 000, since that way ACC:MPR represents xAB0.
In other words, the problem I'm having is that the implementation isn't fully working. I say "isn't fully working" because I've been sitting at my PC for the past few hours using the Step Into function on my LC-3 simulator to go through the code step by step, and I can say for sure most everything in my code is working as intended.
Stepping through MULOOP one step at a time, however, reveals something strange: while the logical shift right works properly for both ACC and MPR (the values in each are divided by two, with truncation, each time), MPR gets divided all the way down to zero before the loop exits.
In fact, ACC used to get zeroed out too at first, when I had my counter set to 16 - this was because the multiplication loop is supposed to iterate N times, where N is the number of bits that make up the numbers you're multiplying, and since the LC-3 is 16-bit addressable, I thought I'd set the counter to 16 bits.
The reason I changed it to 8 is that technically x0010 and x00AB are 8 bit numbers (normally you'd represent them as x10 and xAB, respectively), so I thought maybe 16 iterations of the "multiplication loop" was too much for two 8 bit numbers, and was causing the right shifts within the loop to zero them out (due to being executed too many times).
So that's where I'm at right now. I need to either get ACC to be x00AB instead of x000A (what it is now) or get MPR to be xB000 so that ACC:MPR reads x000A B000, which would be correct for the purposes of the algorithm.
But I don't know what to do. I don't even know what's going wrong. The error must be semantic in nature, because as far as I've seen during program execution, the syntax is correct.
Any help would be appreciated.