1

I am practicing using arrays and loops and I am trying to have the user ENTER less than 100 characters in console to fill up my array. The user can press ENTER whenever they are done entering how ever many characters they want and the program will print out what they entered again.

The program works but I am wondering how the program checks to see if the user press ENTER. I have it so the program will add #-10 to the inputted character and ENTER is x0A which is 10 in decimal. I'm assuming once the program detects this the result is 0 which if false and exits the loop. That is my thought process.

Also, how would I change my code to make it so I can have the exit character be anything?

.orig x3000
LD R1,DATA_PTR  ;load the memory address of array into R1

DO_WHILE_LOOP
    GETC    ;read characters into R0
    OUT     ;print R0 onto console as ASCII
    STR R0,R1, #0   ;stores into memory location in R1
    
    ADD R1,R1, #1   ;increment to next memory address
    ADD R0,R0,#-10  ;looks at inputted character and checks if its is ASCII #10
BRp DO_WHILE_LOOP

LD R0,newline
OUT

LD R1,DATA_PTR

DO_WHILE_LOOP2
    LDR R0,R1,#0    ;load R1 into R0
    OUT             ;print
    ADD R2,R0,#0    ;move R0 to R2
    LD R0,newline   ;newline
    OUT             ;print
    ADD R1,R1,#1    ;increment 
    ADD R2,R2,#-10  ;check if printed character is enter ASCII #10
BRp DO_WHILE_LOOP2  ;if not print next character(loop)

HALT

;Data
DATA_PTR .FILL ARRAY ;DATA_PTR gets the beginning of the ARRAY
newline .FILL x0A   
ARRAY .BLKW #100
.END
henrypham
  • 11
  • 1

1 Answers1

1

I'm assuming once the program detects this the result is 0 which if false and exits the loop.

It's not — that the result 0 here has meaning of "false" — but that the difference between the input character and 10 is 0 meaning it was exactly 0xA or 10(dec).

NB:  the use of BRp can probably be considered a bug, though using usual simulators I've had trouble entering a character whose ascii value smaller than 10.

In high level language terms what it is saying is:

do { ... } while ( in > 10 );

Though using BRnp would mean:

do { ... } while ( in != 10 );

which is more specific to newline.

If you want a different terminal character, change the value subtracted to the value of another character.

LC-3 does not offer subtraction, but it can "add" a negative number.  However, it cannot add a negative number smaller than -16 using the same immediate form of ADD.  So, if you want to check for an ascii character larger than 16, you'll have to use the add register form instead, and use another instruction to load that register with the value, usually using a labeled constant, declared with .FILL and the value you want.

Instead of:

ADD R2,R2,#-10  ;check if printed character is enter ASCII #10
BRp DO_WHILE_LOOP

Do something like the following:

LD R3, value    ; load value to subtract
ADD R2, R2, R3  ; subtract them
BRnp DO_WHILE_LOOP

...
...

value, .FILL #-65 ; letter A, negated.

In LC-3 the ADD instruction sets condition codes.

There are three condition codes, N, Z, and P, — N for negative, Z for zero, and P for positive.  If you add zero to some register, as part of the addition operation, those three flags(condition codes) will be set as follows: N if the original value was negative, Z if the original value is zero, P if the original value is positive — so, < 0, = 0, > 0.

If we use ADD to add a non-zero value, here X (but in its negation, -X) to a register value, V, we get flags that tell us:

  • N = (V < X) i.e. N is true if V < X,
  • Z = (V = X) i.e. Z is true if V = X, and,
  • P = (V > X) i.e. P is true iv V > X

(all ignoring possibilities for overflow).

The BR instruction can then test flags as follows:

If you would like to change the program flow of control on:

relation idea Opcode
< N BRn
>= not N BRzp
= Z BRz
!= not Z BRnp
> P BRp
<= not P BRnz
Erik Eidt
  • 23,049
  • 2
  • 29
  • 53