Computer Sciences Dept.

CS/ECE 252 Introduction to Computer Engineering

Spring 2008 All Sections
Instructor David A. Wood
TAs Spyridon Blanas, Priyananda Shenoy & Shengnan Wang

URL: http://www.cs.wisc.edu/~david/courses/cs252/Spring2008/

Homework 8 // Due at 11am, Monday May 5

Primary contact for this homework: Priyananda Shenoy [shenoy at cs.wisc.edu]

This homework will be submitted electronically; no paper copies will be accepted. You can do this homework in groups of two. Each group must submit one copy of the solution with the names of each one of the members and their section number on all files. We will use a handin program to enforce the time limit and to notify you that your homework has been handed in successfully. For Problems 1,2 and 4 we want a plain-text file, with a file extension of ".txt", with your answer. For Problem 3 we want an assembly source file, with a filename extension of ".asm". Make sure you write the name and section number for both partners at the header of all files you submit.

The Handin program is aviliable on all Windows machines in the CS lab. If you work on your home system, then you need to copy the files from your home system into the CS lab system, and then run the handin program.

Using the handin program in Windows

For example, suppose you work in directory U:\private\cs252\ and you have written answers for the first two problems in file "answers.txt" and the assembly code for problem 3 in file "calc.asm". In order to submit the homework, you'll have to do the following:

  1. Go to Start->Run and type "cmd". This will open the Command Prompt.
  2. Type "S:\handin\bin\handin -c cs252-1 -a hw8 -d U:\private\cs252\", if the student who submits the homework is in section 1, or
    type "S:\handin\bin\handin -c cs252-2 -a hw8 -d U:\private\cs252\", if the student who submits the homework is in section 2.

Problem 1


(10 points)

Which one of the following combinations describe the system described in section 8.2.2 and why?

  1. Memory mapped and interrupt driven.
  2. Memory mapped and polling.
  3. Special opcode for I/O and interrupt driven.
  4. Special opcode for I/O and polling.

Problem 2


(10 points)

An LC3 Load instruction specifies the address xFE02. How do we know whether to load from KBDR or from memory location xFE02?

Problem 3


(80 points)

In this problem you are going to build a simple four function calculator for positive integers.

In order to make it easier to program, we will use the reverse polish notation. In this notation, the operator follows all operands, so 3 + 4 would be written as 3 4 +. Although this notation looks weird at first, we hope that its advantages will become clear when you finish programming this problem.

In your program you will prompt the user to enter a number of an operand by printing the '> ' first. For example, this is how a user (input in red) will compute ((24+19)*3)/10:
> 24
> 19
> +
43
> 3
> *
129
> 10
> /
12

Notice that 129/10=12.9, but the number is truncated to 12.

The user enters lines (a line is a sequence of characters terminated by the ENTER key). The line can be an operand which is a positive decimal number, or an operator which has only a single character which is one of '+','-','*','/'.

When the program is run, the user enters two operands and then an operator. The program must calculate the result, and display it on screen. From then on the user enters one operand and one operator, and the result of the previous operation is used implicitly as the first operand of the new operation.

The ancient Unix utility dc is an RPN calculator. Today you can find it installed on any computer running Unix/Linux, if you want to play with it.

The purpose of this problem is to show you how all the concepts you learned in the course tie together when you have to create a real program. Therefore, we are not interested in seeing a fully-functional calculator: You can assume that all subroutines will always be called with the correct input and that the user will always enter what is expected. Also, you do not have to check for special conditions, such as overflows/underflows.

Since this is a long and complicated program, you cannot do it all at once. You need to break the program down into small units, which is where you will have to use subroutines.

Please adhere to the conventions specified herein, so as to make your code easier to understand. You will lose points if you do not use the same subroutine names or the same registers for argument passing and return types.

  1. (25 points)

    Write the following subroutines which implement all the basic functions:

    • Write the subroutine SUM to add two positive numbers. The first operand is in register R0 and the second one in R1, and the result R0+R1 is to be put in R0.
    • Write the subroutine DIFF to subtract two positive numbers. The first operand is in register R0 and the second one in R1, and the result R0-R1 is to be put in R0.
    • Write the subroutine PROD to multiply two positive numbers. The first operand is in register R0 and the second one in R1, and the result R0*R1 is to be put in R0. (Hint: You can multiply using repeated addition.)
    • Write the subroutine DIV to divide two positive numbers. The first operand is the dividend and is in register R0. The second operand is the divisor and is in R1. The truncated result (quotient) R0/R1 is to be returned in R0. The remainder of the division is to be returned in R1. When the divisor is 0, then both R0 and R1 should be xFFFF. (Hint: Modify the code you wrote for Homework 7, Problem 5.)

  2. (45 points)

    As you may have noticed, the LC-3 lacks instructions which translate a string to a number and a number to a string. In order to have a working calculator, we have to fix this.

    • Write the subroutine ATOI which will parse a null-terminated ASCII string and return the positive integer that this string represents. So, if we pass the string "123", ATOI will return 0x7B, which is the hexadecimal representation of the number 123.

      ATOI will take a single argument, in R0, which will be the address of the first character of the string. ATOI will return the positive integer that this string represents in R0. If the string contains invalid characters (that is, non-numeric characters), R0 must be 0xFFFF.

    • The subroutine ITOA will do the inverse: it will read a number and return the null-terminated string which represents this number. If we pass the value 0x42, ITOA will return the string "66" which is the decimal representation of the input.

      ITOA will take two arguments: R0 will be the integer value; R1 will be the address of the first memory location where the resulting string will be placed. This memory is allocated by the caller. ITOA doesn't return anything.

      For example, suppose that R0 is 0x123 and R1 is 0x4000. When ITOA returns, the memory will have the following layout:

      Memory addressContents (hex)Contents (ASCII)
      0x40000x0032'2'
      0x40010x0039'9'
      0x40020x0031'1'
      0x40030x0000'\0'

      Hint: Both ITOA and ATOI require you to use the subroutines you created earlier. Remember to store the return value from R7 to some temporary storage before calling the subroutine. Otherwise the original return address will be overwritten and the RET instruction will behave erratically next time you call it.

    • The subroutine READLINE reads a line from the keyboard. The input is R0, which contains the address of the memory location where you need to store the line. This is what it should do:
      • Print '> '. (This is called a prompt. This is to indicate to the user that he/she is expected to enter something)
      • Read a character from keyboard, and print the character on the screen. If it is the enter key, terminate the string by placing a NULL in the memory location and return from the subroutine.
      • If it's not the enter key, then copy the ASCII value into the memory location, and increment the address.

      For example, suppose R0 contained x4000 when the program was called. The user typed '2','9','1', [ENTER KEY]. Then your subroutine should put the following into the memory:

      Memory address Contents (hex) Contents (ASCII)
      0x4000 0x0032 '2'
      0x4001 0x0039 '9'
      0x4002 0x0031 '1'
      0x4003 0x0000 '\0'

  3. (10 points)

    Now we'll bring everything together to make our calculator work!

    The basic operation will be:

    1. Read a line by calling READLINE.
    2. Convert the string to an integer using ATOI.
    3. Store the integer in some memory location, say FIRST_ARG.
    4. Repeat the following indefinitely:
      1. Read a line by calling READLINE.
      2. Convert the string to an integer using ATOI,
      3. Store the integer in some memory location, say SECOND_ARG.
      4. Read a line by calling READLINE.
      5. Load the value of FIRST_ARG into R0 and SECOND_ARG into R1. (Why is this required?)
      6. Depending on whether the first character of the input is '+', '-', '*' or '/', call the appropriate subroutine.
      7. Store the result back into FIRST_ARG.
      8. Convert FIRST_ARG into a string using ITOA.
      9. Print the string on the monitor using the PUTS psuedo-opcode.

A skeleton program can be found here. As a bonus, it contains the implementation of subroutine SUM. You can fill in the gaps to get the complete program.

Problem 4


(241 points*)
Make the TA laugh.

*Fine Print: This is a joke.

 
Computer Sciences | UW Home