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