This assignment has three objectives:
1. To introduce you to the process of writing LC3 assembly code.
2. To extend your familiarity with the LC3 instruction set.
3. To help you learn the LC3 tools including the assembler and simulator.
The Assignment
This assignment requires you to write a number of subroutines in LC3 assembly code. As the LC3 has a limited instruction set, you will find that you must write code to perform operations that you take for granted in high level programming languages such as C. For example, the left and right shift operators (<< and >>) do not exist in LC3, nor is there a bitwise OR operator (|). Therefore, you must write functions to perform these operations in terms of instructions that the LC-3 can understand. For all operations, the Param1 and Param2 variables are the two operands and the answer is stored in the Result variable. All numbers are 16-bit integers stored in 2’s complement representation, and all results are limited to 16-bits. No detection of overflow is necessary. Here is a description of the functions you must write:
• IntAdd: Result = Param1 + Param2;
• IntSub: Result = Param1 – Param2;
• IntMul: Result = Param1 * Param2;
• BinaryOr: Result = Param1 | Param2;
• LeftShift: Result = Param1 << Param2;
• RightShift: Result = Param1 >> Param2;
NOTE: For IntMul, you may assume that Param2 is either 0 or positive (Param1 could be anything). For the shift operations, you should fill the vacant positions with 0’s. In other words, you don’t have to worry about sign extension in the left and right shift subroutines because we will be doing logical shifts (as opposed to arithmetic shifts). Also, the number of bits (Param2) for left or right shifts will never be negative or zero.
IMPORTANT:
• Don’t use registers R5, R6, and R7 in this program.
• Don’t change the reserved section of the code.
• Your program must eventually get to the HALT instruction in the main routine. If it doesn’t, your program will be considered wrong.
• Never assume that registers are initialized to 0 by the time your subroutine starts. If you want a register to be initialized to 0, you must do it yourself in your code. If you want to test that you can initialize a register to 0, change the value of the register manually in the simulator to some non-zero value and then run the instruction you think initializes the register.
The protocol for debugging this assignment is presented in the lab. Note that you worked on the first three subroutines in the recitation.
Getting Started
Perform the following steps:
1. Create a P5 directory in your cs270 directory for this assignment.
2. Copy the starter file P5.asm into the directory.
3. Open the file P5.asm with your favorite editor and study it.
4. Assemble the program with the command
~cs270/lc3tools/lc3as P5.asm
5. Implement one of the functions in the file.
6. Fix all assembler errors and make sure that P5.obj and P5.sym are created.
7. Start the simulator with the command
~cs270/lc3tools/lc3sim-tk &
8. Use the button to browse for and load your object code, called P5.obj.
9. Click on a memory location that you want to change. For example Option, Param1, or Param2.
10. Click in the Value field and enter the value you want to store in that memory location and press the left Enter key on the keyboard.
11. Repeat steps 9 and 10 for each value you need to set. To test IntAdd, you need to make Option = 0. To test IntSub, you need to make Option = 1. And so on.
12. Place a breakpoint at the HALT instruction in the Main subroutine. Run your program by clicking on the Continue button.
13. When the program stops, examine the value stored at memory location Result.
14. Hit the Reset button and return to step 9) to start a new test. When you reset the simulator, all breakpoints will be cleared and you will need to place them again. Also, the memory locations that you changed manually will be reset to the default values. An alternative to changing the memory locations manually every time you reset the simulator is to hard code the values in the program. To do this, change the .BLKW 1 to .FILL xNNNN for the Option, Param1, and Param2 labels (NNNN is the hexadecimal number you want). This is the one change you’re allowed to make to the reserved section. You may want to use the Step button instead of Continue if you need to see what happens after every instruction in your program.
Note: when programming in assembly, it is easy to forget the syntax of each instruction (e.g., where do the source and destination registers go). Please refer to this document (starting on page 6) for a description of the assembly syntax for each LC-3 instruction.
Right Shifting
Unlike left shifting, right shifting is not a trivial operation to implement in the LC-3. Let’s go through an example of how to right shift. For this example, we will be using 5 bits instead of 16.
Suppose I want to do 10110 >> 2.
First, I will initialize my result to be 00000. The idea is that I will walk through the bits copying from left to right as follows:
Step 1
Notice that the first two bits starting from the right will go away. Hence, I’ll start by copying bit 2 in my parameter to bit 0 in my result:
Parameter = 10110
Result = 00001
Step 2
Now, I move to the next bit. The next bit is 0, so I don’t need to copy that bit to the result because the result was initialized to 0’s:
Parameter = 10110
Result = 00001
Step 3
Now, I move to the next bit. The next bit is 1, so I need to copy that to the result:
Parameter = 10110
Result = 00101
Step 4
It looks like I’ve gone through all the bits in the parameter, so I’m done.
Parameter = 10110
Result = 00101
To inspect and copy bits, you will need to use masks and bitwise operations. Below is a flowchart that shows you the general algorithm for right shifting. You will need to take care of the details. Remember that numbers in the LC-3 are 16 bits wide (not 5).
Grading Criteria
Preliminary Testing (25 points):
• Program assembles without errors or warnings. (5 points)
• Correct implementation of the IntAdd subroutine. (5 points)
• Correct implementation of the IntSub subroutine. (5 points)
• Correct implementation of the IntMul subroutine. (10 points)
Final Testing (75 points):
• Correct implementation of the BinaryOr subroutine.
• Correct implementation of the LeftShift subroutine.
• Correct implementation of the RightShift subroutine.
Assignment Submission
Submit the single file P5.asm to the Checkin tab on the course website, as you were shown in the recitation, and check your preliminary results.