CS 33: Lab #05

CS 33: Computer Organization


LAB 05: Assembly Language on the LC-3

Due 11:59pm Wednesday, October 8.

The program handin33 will only submit files in the cs33/lab/05 directory. (You should run update33 first to set up the directory and create any necessary files.)

Remember: You are encouraged to work with a partner.

In this lab, we will write assembly language programs for the LC-3, assemble them to object code for the LC-3 (lc3as), and then run them in the LC-3 simulator (lc3sim-tk).

Your programs must follow these following guidelines:

  • Each file should be named using the name provided, and you must follow any instructions concerning particular memory addresses to use. Without this, it makes grading your programs exceedingly difficult.
  • Each file should assemble without errors using the lc3as program.
  • Numbers will be assumed to be binary unless you preceed them with a # (e.g. #25) for decimal values, or x (e.g. x1F) for hexadecimal values.
  • Sequences of code which perform a single logical operation should be commented above the block, and a newline should separate it from the next block:
            ;; Store in R3 the value of -R2
            NOT R3, R2
            ADD R3, R3, #1
            ;; Shift R3 to the left two places
            ADD R3, R3, R3
            ADD R3, R3, R3
  • All data items should be appropriately labeled
    HIMASK  .FILL   xFF00
    CHAR_A  .FILL   x0041
  • All functions that you write should
    • be adequately commented,
    • save the initial state of any registers that it uses,
    • store arguments and return values in its own reserved memory space, and
    • restore the initial state of registers upon exit.

For this lab assignment, you will write one LC-3 assembly language program. Your program should begin at x3000 and you should not make any assumptions about the initial state of registers or memory locations.

You will store your answers in the file lab05.asm.

  1. Write a function called MULTFN which takes two arguments named ARG1_MULT and ARG2_MULT, multiplies them together, and stores the result in RET_MULT. You can use any code we wrote in class as a basis for your solution. You should assume that both arguments are zero or positive.
  2. Write a function called MULT10FN which takes one argument named ARG_MULT10, multiplies it by 10, and stores the result in RET_MULT10. Your solution should use the MULTFN function.
  3. Write a function called DIVMODFN which takes two parameters named ARG1_DIVMOD and ARG2_DIVMOD. In DIV_DIVMOD, you should store the (integer) result ARG1_DIVMOD divided by ARG2_DIVMOD. In MOD_DIVMOD, you should store the result of result ARG1_DIVMOD mod ARG2_DIVMOD.
  4. Write a function called DIV10FN which takes one argument, ARG_DIV10, and stores into RET_DIV10 the result of dividing ARG_DIV10 by 10. Your solution should use the DIVMODFN function.

In the remaining portion of the lab, you will reimplement your solution to the decimal-binary conversion program of the last lab, and you will add new functionality. Your solution will make use of the MULT10FN and DIV10FN which you wrote above.

I would strongly advise that you not refer to your previous machine language solution when writing this solution: the assembly language solution should be far more elegant due to the availability of labels for variables and functions. Note: Continue to use the lab05.asm file.

  1. Write a function called INDIGITSFN which reads in up to 4 digits from the keyboard and stores them in a block of memory you have reserved labeled DIGITS. The function takes no arguments and has no return value. Your function should:
    • only accept the characters 0-9, and
    • store no more than 5 words in memory (up to 4 digits plus a marker to indicate the end of the input).
    How you chose to implement these two conditions is up to you.
  2. Write a function called DEC2BINFN which converts the contents of the memory location DIGITS to binary. The function has no arguments and stores its result in RET_DEC2BIN. The correct solution will use the MULT10FN function. Note: You should assume that the correct digits are already in DIGITS. Do not call the INDIGITSFN in this function.
  3. Write a function called PRINTBFN which outputs the contents of its single argument, ARG_PRINTB in binary. The function has no return value.
  4. Write a function called BIN2DECFN which takes an argument, ARG_BIN2DEC and converts this value to its decimal equivalent (as a string, similar to what you stored in DIGITS). You should reserve a block of 6 words (for up to 5 digits plus a marker to indicate the end of the string) called RET_BIN2DEC which will store the decimal string. The correct solution will use the DIV10FN function. Note: The value in RET_BIN2DEC needs to be a string in the LC-3 sense: that is, if you load the address RET_BIN2DEC into R0 (LEA R0, RET_BIN2DEC) and then call PUTS, the string should be printed to the screen.
  5. Be sure your "main program" requires no more than these statements:
    	.ORIG	x3000
    	;; Read digits in DIGITS
    	;; Convert contents of memory location DIGITS
    	;; from decimal and store in R3
    	;; Print contents of register R3 as a binary number
    	;; Convert contents of register R3 to decimal, 
    	;; and then print it out
    	ST	R3, ARG1_BIN2DEC