loopsassemblyadditionlc3lc3-trap

Printing double digit numbers in LC-3


Been learning about LC-3 lately and was wondering how do I go about printing a number that's bigger then 9? In this program I made it asks for width and length and multiplies the two to get the area of the shape. My problem is any output bigger then 9 it starts printing a letter or a number not close to what I wanted. How should I go about doing this? my code:

.ORIG x3000

; Reset Registers
AND R0, R0, #0
AND R1, R1, #0
AND R2, R2, #0
AND R3, R3, #0
AND R4, R4, #0
AND R5, R5, #0
AND R6, R6, #0
AND R7, R7, #0

LEA R0, numberone
PUTS
GETC
OUT
LD R3, HEXN30 
ADD R0, R0, R3
ADD R1, R0, #0


LEA R0, numbertwo
PUTS
GETC
OUT
ADD R0, R0, R3
ADD R6, R0, #0
LOOP
      ADD R2, R2, R1
      ADD R6, R6, #-1
BRp LOOP

LEA R0, MESG 
PUTS
ADD R0, R2, x0

LD R2, NEG_TEN  
ADD R2, R2, R0  
BRn JUMP    
AND R4, R4, #0  
ADD R4, R4, R2  
LD R0, ASCII_1 
OUT    
AND R0, R0, #0  
ADD R0, R0, R4  

JUMP

LD R3, HEX30 ;add 30 to integer to get integer character
ADD R0, R0, R3
OUT 

HALT ;{TRAP 25}


numberone  .stringz "\nPlease enter the length: "
numbertwo  .stringz "\nPlease enter the width: "
MESG .STRINGZ  "\n\nThe Area of the Rectangle is: "
HEXN30 .FILL xFFD0 ; -30 HEX
HEX30 .FILL x0030 ; 30 HEX
NEG_TEN .FILL #-10
ASCII_1 .FILL x0031 ; ASCII char '1'
.END

Example Output:

Please enter the length: 4
Please enter the width: 5
The area of the object is: 20

Solution

  • This code will always print 1:

    LD R0, ASCII_1 
    OUT 
    

    There's no chance for it to print a 2 like you'd want from 4 times 5.


    The next character prints as : because you have 10 in R4, as you haven't subtracted 10 enough times in the division by repetitive subtraction.  You've only subtracted 10 once and 20 needs to have 10 subtracted twice (to get 0 as the remainder).


    You should be able to see the first problem by simply reading the code there.  How could loading an ascii 1 and printing it do anything other than print a 1?  So there is some missing code there.

    The latter problem is a form of off-by-one error (looping one to few iterations), which is something you should be looking for during single-step debugging.  You want your division by repetitive subtraction to leave you with a remainder between 0 and 9 — definitely not 10!

    Boundary conditions are very error prone.  Using < when it should be <= (or vice vesa), for example, can result in an off by one error.  What we do is try to use idioms to avoid these problems (like for(int i = 0; i < n; i++)), but when an idiom isn't applicable, then you want to be suspicious of and test those boundary conditions: at the boundary, at one less, at one more.