LC-3 Assembly Examples
Multiply by 10
;; Set R0 to 10*R1
.ORIG x3000
mul10 ADD R0,R1,R1 ; R0 == 2*R1
ADD R0,R0,R0 ; R0 == 4*R1
ADD R0,R0,R1 ; R0 == 5*R1
ADD R0,R0,R0 ; R0 == 10*R1
HALT
XOR registers R1 and R2
;; Set R3 to R1 ^ R2
;; i.e. OR( AND(NOT(R1),R2), AND(R1,NOT(R2)))
;; i.e. NOT(AND(NOT(AND(NOT(R1),R2)),NOT(AND(R1,NOT(R2)))))
.ORIG x3000
xor NOT R1,R1
AND R3,R1,R2
NOT R1,R1
NOT R2,R2
AND R4,R1,R2
NOT R2,R2
NOT R3,R3
NOT R4,R4
AND R3,R3,R4
NOT R3,R3
HALT
Compute the "population" of R1
;; Set R0 to the number of bits "on" in R1
.ORIG x3000
pop AND R0,R0,#0
ADD R1,R1,#0 ;; test the msb
BRzp skipf
ADD R0,R0,#1
skipf AND R2,R2,#0
ADD R2,R2,#15
loop ADD R1,R1,R1 ;; now test the other 15
BRzp skip
ADD R0,R0,#1
skip ADD R2,R2,#-1
BRp loop
HALT
.END
Compare a and b -- Try 1
;; Sets r to
;; <0, if a<b
;; =0, if a==b
;; >0, if a>b
;; Follows the conventions of C's qsort function
;; and Java's comparable interface.
.ORIG x3000
LD R1,a
LD R2,b
NOT R2,R2
ADD R2,R2,#1
ADD R2,R1,R2 ;; R2 <- a-b
ST R2,r
HALT
a .FILL #20000
b .FILL #-20000
.BLKW 1
.END
;; Unfortunately, this can fail if a-b overflows!
Compare a and b -- Working
;; Really sets r to
;; <0, if a<b
;; 0, if a==b
;; >0, if a>b
;; Returned value
;; | a<0 | a≥=0 |
;; ------ +-------+-------+
;; b<0 | a-b | a |
;; ------ +-------+-------+
;; b>=0 | a | a-b |
;; ------ +-------+-------+
.ORIG x3000
cint LD R1,a
BRn aNeg
;; a>=0, if here
LD R2,b
BRn retA
BR cmp
;; a<0, if here
aNeg LD R2,b
BRn cmp
;; BR retA
;; a and b have different signs
retA ST R1,r
BR leave
;; a and b have same sign
cmp NOT R2,R2
ADD R2,R2,#1
ADD R2,R1,R2
ST R2,r
leave HALT
a .FILL #-20000
b .FILL #20000
r .BLKW 1
.END
Compare a and b -- Still working
;; Really sets r to
;; <0, if a<b
;; 0, if a==b
;; >0, if a>b
;; Returned value
;; | a<0 | a>=0 |
;; ------ +-------+-------+
;; b<0 | a-b | a |
;; ------ +-------+-------+
;; b>=0 | a | a-b |
;; ------ +-------+-------+
.ORIG x3000
cint LD R3,b15
LD R1,a
LD R2,b
AND R3,R3,R1 ;; R3 contains the sign bit of R1.
ADD R3,R3,R2 ;; Negative only if R1 and R2
BRzp cmp ;; have different signs.
;; a and b have different signs
retA ST R1,r
BR leave
;; a and b have same sign
cmp NOT R2,R2
ADD R2,R2,#1
ADD R2,R1,R2
ST R2,r
leave HALT
b15 .FILL x8000
a .FILL #-20000
b .FILL #20000
r .BLKW 1
.END
Character count
;; Counts the number of times a character occurs in a string
;; Character -- stored at x4000
;; String -- stored at x5000
;; Result -- stored at x6000
.ORIG x3000
nmChr AND R0,R0,#0
LD R1,AFILE ;; R1 has address of the string
LDI R2,ALOOK4 ;; R2 has the value of the string
NOT R2,R2
ADD R2,R2,#1
ALOOP LDR R3,R1,#0
BRz STOPIT ;; Leave loop on zero word
ADD R3,R3,R2
BRnp NOCOUNT
ADD R0,R0,#1
NOCOUNT ADD R1,R1,#1
BR ALOOP
STOPIT STI R0,ACOUNT ;; Count is stored
HALT
ALOOK4 .FILL x4000
AFILE .FILL x5000
ACOUNT .FILL x6000
.END
AND a vector of words
;; AND's a vector of words
.ORIG x3000
andV AND R0,R0,#0
ADD R0,R0,#-1 ;; Set R0 to all one's
LEA R2,VECT ;; Use LEA to get address of vector
LD R1,SIZE
BRzp STOPIT ;; Return all one's if nothing to AND
LOOP LDR R3,R2,#0
AND R0,R0,R3
ADD R2,R2,#1
ADD R1,R1,#-1
BRp ALOOP
STOPIT ST R0,RESULT
HALT
SIZE .FILL 5
VECT .FILL xBEEF
.FILL x89AB
.FILL xFFFF
.FILL x89AB
.FILL x2008
RESULT .BLKW 1
.END
Reverse a string
;; Reverse a string
.ORIG x3000
rev LEA R0,FILE ;; R0 is beginning of string
ADD R1,R0,#-1
LOOP1 LDR R3,R1,#1 ;; Note -- LDR "looks" at the word past R1
BRz DONE1
ADD R1,R1,#1
BR LOOP1
DONE1 NOT R2,R0
ADD R2,R2,R1
;; R0 == address of first character of string
;; R1 == address of last character of string
;; R2 == size of string - 2 (Think about it....)
LOOP2 ADD R2,R2,#0
BRn DONE2
LDR R3,R0,#0 ;; Swap
LDR R4,R1,#0
STR R4,R0,#0
STR R3,R1,#0
ADD R0,R0,#1 ;; move pointers
ADD R1,R1,#-1
ADD R2,R2,#-2 ;; decrease R2 by 2
BR LOOP2
DONE2 HALT
FILE .STRINGZ "This is so much fun!"
.END