Introduction
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 must be appropriately labeled
HIMASK .FILL xFF00
CHAR_A .FILL x0041
- All functions that you write must
- 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.
- 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 for your solution. You can assume that both arguments are zero or positive.
- 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.
- 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. For example, if
ARG1_DIVMOD stores the (decimal) value #23 and
ARG2_DIVMOD stores the value #5, then after the function is
completed, DIV_DIVMOD will store #23 / #5 = #4 and
MOD_DIVMOD will store #23 % #5 = #3.
- 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.
- Write a function called INDIGITSFN which reads in up to
4 digits from the keyboard and stores them in a block of memory
(.BLKW) 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 (16-bit values) 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.
- 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.
- Write a function called PRINTBFN which outputs the
contents of its single argument, ARG_PRINTB in binary. The
function has no return value.
- 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.
- Be sure your "main program" requires no more than these statements:
.ORIG x3000
;; Read digits in DIGITS
JSR INDIGITSFN
;; Convert contents of memory location DIGITS
;; from decimal and store in R3
JSR DEC2BINFN
LD R3, RET_DEC2BIN
;; Print contents of register R3 as a binary number
ST R3, ARG1_PRINTB
JSR PRINTBFN
;; Convert contents of register R3 to decimal,
;; and then print it out
ST R3, ARG1_BIN2DEC
JSR BIN2DECFN
LEA R0, RET_BIN2DEC
PUTS
HALT