CS 33: Lab #03

CS 33: Computer Organization

 

LAB 03: Introduction to the LC-3

Due 11:59pm Wednesday, Sept 24

The program handin33 will only submit files in the cs33/lab/03 directory. (You should run update33 first to set up the directory and create the lab03.txt file.)

You are encouraged to work with a partner; however, you may work alone if you choose to do so.

When we begin to write programs on the LC-3, we will talk about the instruction set of the machine. The instruction set describes the complete set of supported operations. As we have seen, Appendix A (section A.3, p.523) in the text book contains a complete description of the LC-3 instruction set.

  1. How many instructions are in the LC-3 instruction set? Contrast this with the Intel x86 instruction set which is (a subset of) the instruction set of nearly every Intel desktop processor you have probably ever used, including all the Pentium, Xeon, Core Solo, and Core Duo models. The x86 instruction set contains well over 150 instructions.
  2. The LC-3 and x86 instruction sets both contain the operations AND, ADD, and NOT. One important instruction from the x86 instruction set that is excluded from the LC-3 is SAL. The SAL instruction performs a left shift on a register. The result of a left shift is that each of the bits in the register are moved over one position to the left. The leftmost bit is discarded and then rightmost bit is replaced with a zero.
    1. Recalling that the LC-3 has a word size of 16-bits, the LC-3 would store the 2s complement integer 23 in memory as 0000 0000 0001 0111. If we performed a shift left on this value, what would the result be in both binary and decimal?
    2. What is the 2s complement notation for -50? What is the result (in binary and decimal) of performing a left shift on this value?
    3. Your answers to part a. and b. should give you insight into what left shift does to 2s complement integers. Given a more common description of this operation.
    4. How would you compute R2 = SAL(R1) on the LC-3? Your answer should not be LC-3 instructions written in binary, but rather something like R2 = R0 ADD R1, or R3 = NOT R4. You may only use the ALU (arithmetic logic unit) operations AND, ADD, and NOT
  3. The LC-3 implements two versions of the ADD instruction. The first adds two 16-bit registers (the first row in Figure A.2 on page 525) and the second adds one 16-bit register to an immediate 5-bit value (the second row).
    1. What is the largest value that can be stored in the 5-bit immediate position? (Remember that this is a 2s complement integer.)
    2. If the 2s complement representation of the number 727 is stored in register R0 and you wish to compute R2 = R1 ADD 727, it is easy to do since we can use the first version of ADD: R2 = R1 ADD R0. But, what if 727 is not stored in a register (or in memory)? Provide a sequence of instructions that compute R2 = R1 ADD 727. You may use other registers as temporary storage, but R1 must not be modified. You may only use ALU operations and your answer should be in the same format as question 2. HINT: It may help you if you assume that R3 contains the value 0, or you can go ahead and answer question 5 first, then come back to complete your answer without that assumption. CHALLENGE: Without making the assumption that R3 is 0, can you complete this in 11 operations or less?
  4. Another instruction supported by the x86 instruction set but not supported by the LC-3 instruction set is SUB, which performs subtraction. Assuming that the registers R0 and R1 each contain 2s complement integers, how would you compute R2 = R0 SUB R1? (Again, same format as question 2 using only the ALU operations.)
  5. A common operation performed in programming is setting a value to zero. Show two ways to perform the assignment R0 = 0. Both ways should take 3 or less instructions. You may use other registers as temporary storage if necessary. Your answer should work regardless of the initial value of R0. (Again, same format as question 2 using only the ALU operations.)
  6. Assume that R0 contains a positive 2s complement integer. Write a sequence of LC-3 statements (same format/only ALU operations) that sets R1 = 1 if R0 is odd, otherwise it sets R1 = 0. You may only use ALU operations.
  7. Another x86 instruction excluded from the LC-3 is the ROL instruction which performs a left rotate. Left rotating is similar to left shifting (SAL), except that instead of throwing away the leftmost bit and forcing the rightmost bit to 0 (which we do in shifting), we make the rightmost bit equal to the previous leftmost bit. For example, if R0 = 1001 0100 0010 0000, then the after executing R1 = ROL(R0), R1 would store the value 0010 1000 0100 0001.
    1. Using the 2s complement values from questions 2a. and 2b., what is the result of performing a left rotate?
    2. Assume that the LC-3 supported a fictional instruction called SIGN(DR, SR) which did the following:
          if SR >= 0 then
             DR = 0
          else
             DR = 1
      Write a sequence of LC-3 instructions (using the ALU instructions + the SIGN instruction) which performs R1 = ROL(R0).
    3. Write a sequence of statements which stores in R1 the number of 1's in the 4 leftmost bits of R0 (using the ALU instructions + the SIGN instruction).
  8. Sometimes data only requires 8 bits of storage space. Generally, characters (such as the letter 'A') are stored using only 8 bits (1 byte). However, the LC-3 has a word size of 16-bits (2 bytes), which means that if we store a character in a memory location, we end up wasting 1 byte of the memory space per character. On a modern 64-bit processor, we would be wasting 56 bits (7 bytes) for each 1 byte character. That's a lot of waste! To get around this problem, multiple characters can be stored in a single memory location using what is known as packing. The idea is simple: we use the first 8 bits (bits [15:8]) of the 16-bit word to store one character, and we use the second 8 bits (bits [7:0]) to store the next character.
    1. Assuming that R0 contains the ASCII encoding of the letter 'A' and R1 contains the ASCII encoding of the letter 'B', write a sequence of LC-3 statements (using the ALU operations + the SIGN instruction) that packs the contents of R0 and R1 into R2 (with R0 occupying [15:8]).
    2. Assuming that R2 contains two packed bytes (such as the result of performing part a. above), write a sequence of LC-3 statements (using the ALU operations + the SIGN instruction) that unpacks the contents of R2 into R0 (bits [15:8]) and R1.
  9. The LC-3 has three methods for loading data from memory into a register.
    1. One method is LD which performs the operation DR = LD(PCoffset9). If you picture memory as being a giant list (or array) of 16-bit words, then the effect of this statement is DR = mem[PC + PCoffset9], where PC is the current value of the Program Counter. Using the LD instruction, what range of memory addresses do you have access to (relative to the PC)?
    2. Recall that the Program Counter is incremented at the same time as the current instruction is loaded into the Instruction Register (IR). If the instruction R2 = LD(x14A) is located in memory location x3004, what memory address is loaded into R2 when this instruction is executed?
    3. Another method for loading values from memory is LDR whose format is DR = LDR(BaseR + offset6). Similar to LD, this statement has the effect of DR = mem[BaseR + offset6], with the value stored in the register BaseR replacing the PC from the LD instruction. This allows you to specify memory addresses relative to the value stored in a register, rather than the Program Counter. Using the LDR instruction, what range of memory addresses do you have access to (relative to the BaseR)?
    4. The final way of loading values into memory is using the LDI instruction whose format is the same as LD: DR = LDI(PCoffset9). The LDI statement has the effect of DR = mem[mem[PC + PCoffset9]]. Be sure to compare this to the LD statement to see how they are different. Write a series of statements (again, in a similar format to those shown so far) that perform R2 = LDI(x00F) without using the LDI instruction. For this question, you can use the LD and LDR instructions.