LC-3 Encryption Program
30 November -0001
This LC-3 program performs simple encryption and decryption of character strings. The encryption algorithm consists of a numeric key from 1 to 9. This key is used to encrypt or decrypt the input string by toggling the low order bit of each character and then adding the key to encrypt and subtracting the key to decrypt each character (depending on the specification of the input). This program was written as part of a class assignment and is assumed to work on character strings of 10 characters or fewer.
My main motivation for posting this code is the dearth of LC-3 code samples available online. LC-3 (or Little Computer 3) is an architecture used for instructional purposes only.
;Name: Justin Klein Keane ;Email: justin@madirish.net ;Date Last Modified: Oct 18, 2007 ;Encryption Program .ORIG x3000 ;start of program ;FILL IN YOUR CODE BELOW LEA R0, P1 PUTS ;output the instructions IN1 AND R3,R3,#0 ;clear R3 IN ;Get the input ADD R3,R0,#0 ;put the input in R3 for holding LD R6, CHARE ;Use R6 to hold -E NOT R6,R6 ADD R6, R6, #1 ADD R2, R3, R6 ;Use R2 to test value of R3 (input) BRz CONT LD R6, CHARD ;Use R6 to hold -D NOT R6,R6 ADD R6, R6, #1 ADD R2, R3, R6 ;Use R2 to test value of R3 (input) BRz CONT BRnp WARN1 CHARD: .FILL x0044 ;value of E CHARE: .FILL x0045 ;value of D s4100 .FILL x4100 HEX29: .FILL x0029 HEX3A: .FILL x003A HEX30: .FILL x0030 CONT LD R4, s4100 ;use R4 to store our target location STR R3, R4, #0 ;put R3's contents at x4100 IN2 AND R1,R1,#0 ;clear R1 AND R2,R2,#0 ;clear R2 AND R3,R3,#0 ;clear R3 AND R4,R4,#0 ;clear R4 LEA R0,P2 PUTS IN ;Get the input ADD R3,R0,#0 ;put the input in R3 for holding ;We will check the input by subtracting 30 (hex) and making sure ;the result is positive or zero. Next we will subtract 3A and ;make sure the result is negative. If both conditions ;are true the vaule must be between 30 and 39 (ASCII 0-9) LD R1, HEX30 ;Use R1 to hold -30 hex NOT R1, R1 ADD R1, R1, #1 ADD R2, R3, R1 ;Use R2 to test value of R3 (input) BRn WARN2 LD R1, HEX3A ;Use R1 to hold -3A NOT R1,R1 ADD R1, R1, #1 ADD R2, R3, R1 ;Use R2 to test value of R3 (input) BRzp WARN2 ;before storing we'll turn this into a real number, not the ASCII value AND R1 R1, #0 LD R1, HEX30 NOT R1, R1 ADD R1, R1, #1 ADD R4, R4, R0 STORE LD R4, s4101 ;store the value at x4101 ADD R3, R3, R1 ;get the corrected value (for the right hex as opposed to ASCII) STR R3, R4, #0 CONT2 ;Continue right along LEA R0, P3 PUTS ;ask the user for a string AND R1,R1,#0 ;clear R1 AND R2,R2,#0 ;clear R2 AND R3,R3,#0 ;clear R3 AND R4,R4,#0 ;clear R4 AND R5,R5,#0 ;clear R5 for use as a counter ADD R2, R2, x000A ;use R2 as the test value NOT R2, R2 ;make R2 negative (so we can add and test for 0) ADD R2, R2, #1 LD R4, s4102 ;store the value starting at x4102 LOOPIN AND R3,R3,#0 ;clear R3 IN ADD R3, R0, #0 ;put the character in R3 STCHR STR R3, R4, #0 ADD R4, R4, #1 ;increment the counter ADD R3, R3, R2 BRnp LOOPIN ;if this is zero we're done inputting ;now it's time to do the encryption ;start with the first item in the string, ;encrypt it and output it to the screen NOT R4,R4 ADD R4, R4, #1 ;make R4 negative E/D for counter testing AND R3,R3,#0 ;clear R3 - to use for the encryption key LD R3, s4101 AND R5,R5,#0 ;clear R5 for use as a counter LD R5, s4102 ;load the start into R5 LD R3, s410B ;load the start of storage for output in R7 ;LEA R0, P4 ;PUTS ;output the instructions LOOPOUT ADD R3, R3, #1 ;increment storage location (starts with x410C) AND R2,R2,#0 ;clear R2 (use to test EOL) ADD R2, R2, x000A ;use R2 as the test value NOT R2, R2 ;make R2 negative (so we can add and test for 0) ADD R2, R2, #1 AND R4, R4, #0 ;clear R4 for test output AND R1,R1,#0 ;clear R1 (used to hold the character in question) AND R6,R6,#0 ;clear R6 for misc use LDR R1, R5, #0 ;load the character we're working on into R1 ADD R5, R5, #1 ;increment the counter ADD R4, R1, R2 ;check to see if this character is the newline BRz GOODBYE GETOP AND R2, R2, #0 ;clear R2 to test for Encryption/Decryption LD R2, s4100 ;load the value of x4100 into R2 (LD then LDR) test if we're encrypting or decrypting LDR R2, R2, #0 LD R6, CHARNE ADD R2, R2, R6 BRz ENCHAR LD R2, s4100 LDR R2, R2, #0 LD R6, CHARND ADD R2, R2, R6 BRz DECHAR CHARNE: .FILL xFFBB ;this is -E CHARND: .FILL xFFBC ;this is -D s410B: .FILL x410B ;this is the start of the storage location ENCHAR ;encrypt the character in R1 ;the first step is to toggle the least significant bit (add one if the char is even, minus one if it's odd) ADD R2, R1, #0 ;load the character in question into R2 AND R6, R6, #0 ;clear R6 ADD R6, R6, 2 ;load -2 into R6 (we use this to test for even or odd) NOT R6, R6 ADD R6, R6, #1 EVNODD ADD R2, R2, R6 ;decrement R2 by 2, looking for a result of 0 or -1 BRz ENCEVN ;R2 is even BRn ENCODD ;R2 is odd BRp EVNODD ;loop again ENCEVN ;it's even, we have to add one ADD R1, R1, x0001 BRnzp ENC ENCODD ;it's odd, we have to sub one AND R0, R0, #0 ;load R0 with -1 ADD R0, R0, #1 NOT R0, R0 ADD R0, R0, #1 ADD R1, R1, R0 ENC ;now we'll do the rest of the encryption LD R0, s4101 ;load the encryption key into R0 (from x401) LDR R0, R0, #0 ADD R0, R1, R0 ;add the encryption key STR R0, R3, #0 ;store the character ;OUT ;output the character BRnzp LOOPOUT ;get the next character DECHAR ;decrypt the character (first subtract the key then do even odd test to flip least significant bit) LD R0, s4101 ;load the encryption key into R0 (from x401) LDR R0, R0, #0 NOT R0, R0 ADD R0, R0, #1 ADD R0, R0, R1 ;load the character into R0, we'll manipulate it there ADD R2, R0, #0 ;clear R2, for use testing even/odd of the char AND R6, R6, #0 ;clear R6 ADD R6, R6, 2 ;load -2 into R6 (we use this to test for even or odd) NOT R6, R6 ADD R6, R6, #1 DEVNODD ADD R2, R2, R6 ;decrement R2 by 2, looking for a result of 0 or -1 BRz DECEVN ;R2 is even BRn DECODD ;R2 is odd BRp DEVNODD ;loop again DECEVN ;it's even, we have to add one ADD R0, R0, x0001 BRnzp DENC DECODD ;it's odd, we have to sub one AND R1, R1, #0 ;load R1 with -1 ADD R1, R1, #1 NOT R1, R1 ADD R1, R1, #1 ADD R0, R1, R0 DENC STR R0, R3, #0 ;store the character ;OUT ;output the character BRnzp LOOPOUT ;get the next character GOODBYE LEA R0, P4 PUTS ;output the final message LD R1, s410B FINLOOP ADD R1, R1, #1 ;increment the output (start with x410C) LDR R0, R1, #0 ;load the next character into R0 ADD R0, R0, #0 ;check to see if we're done BRz ENDER OUT BRnzp FINLOOP ENDER LEA R0, GB ;close out nicely PUTS HALT WARN1 LEA R0, ILLEGAL PUTS BRnzp IN1 WARN2 LEA R0, ILLEGAL PUTS BRnzp IN2 s4101: .FILL x4101 s4102: .FILL x4102 P1: .STRINGZ "Type E to Encrypt or D to Decrypt: \n" P2: .STRINGZ "\nEnter Encryption Key value between 1 and 9:\n" P3: .STRINGZ "\nInput a msg <= 10 chars, then press enter:\n" P4: .STRINGZ "\nEncrypted/Decrypted msg is:\n" GB: .STRINGZ "\n" ILLEGAL: .STRINGZ "\nIllegal Input, Try Again!\n" KEY: .FILL x4101 NEG1: .FILL xFEEE NEG2: .FILL xFFFE ;this is -2 Newline: .STRINGZ "\n"; .END