assemblylc3

Is my LC3 solution correct for finding the length of an increasing sequence?


I am asked to create a program in LC3 that recognises the maximum length of an increasing subsequence in a sequence of numbers.

Ex. {1,2,3,5,2,2,4,5,6,8,3,4}

solution: maximum increasing subsequence: {2,2,4,5,6,8} , maximum length of an increasing subsequence: 6

In order to do that , I am asked to create a subroutine called MAX_LEN that computes max(x,y) of two numbers x,y and has input x,y in R2,R5 and should give Output: max(x,y) in R5. Also I have to use another INC_SUB_LEN which computes the length of the first increasing subsequence from a given address. Input address is R0 and output length should be in R2. Maximum length so far in R5. I should also use the MAX_LEN subroutine. The large sequence from which we will find the subsequences is stored in adress DATA and its length in adress LENGTH. I am also given the commands at the end LENGTH .FILL x5000 and DATA .FILL x5001.

I am new in LC3 programming so I wrote my program on paper. Can someone find any errors in my solution? if yes , how could I correct them??

My solution:

.ORIG x3000
LD R0,DATA
LD R1,DATA
LOOP1 JSR INC_SUB_LEN
ADD R1,R1,#1
LD R4,LENGTH
NOT R4,R4
ADD R4,R4,#1
ADD R3,R1,R4
BRn LOOP1

INC_SUB_LEN 
LOOP ADD R2,R2,#1 
ADD R4,R0,#0
LDR R6,R0,#1
LDR R0,R0,#1
NOT R6,R6
ADD R6,R6,#1
ADD R7,R4,R6
BRnz LOOP
JSR MAX_LEN
RET

MAX_LEN 
NOT R5, R5
ADD R5, R5, #1
ADD R3,R2,R5
BRnz ELSE
ADD R5,R2,#0
NOT R5,R5
ADD R5,R5,#1
ELSE NOT R5,R5
ADD R5,R5,#1
RET


LENGTH .FILL x5000
DATA .FILL x5001
.END

Solution

  • There's a web-based simulator: https://wchargin.github.io/lc3web/ Using this simulator, you can manually enter data into the memory map, so even if you can't fill in the memory space in the code you can do it in the GUI.

    Additionally, code documentation is super critical in assembly because it does not lend itself well to self-documentation. Make sure that labels are meaningful and you should have a block comment indicating register usage "strategy" (i.e. which ones are temporary and which are used in a longer scope and should be saved to the stack before overwriting them). You should also have a block comment indicating the intention of every logical block, and these blocks can tend to be quite small because even simple arithmetics can be 10-20 lines.

    On the second line, "LD R0, DATA" takes the actual data at the label; according to your description, you want to load the address instead of the data, for this you use "LEA" rather than "LD". This will be required for your LDR later on to function correctly.

    I'm not clear why you initialize LENGTH to be 0x5000, or why DATA is a .FILL if it's intended to be a sequence. To block memory for a larger (more than one word) of data, you should use .BLKW and the number of bytes. This reserves the space, and you can manually insert data into a simulator (pointy-clicky style) if you like, or use some other technique to write the data programatically.