Homework 7 [Due at Lecture on Fri, April 19]
Primary contacts for this homework: Pradip Vallathol [pradip16@cs.wisc.edu] and Rebecca Lam [rjlam@cs.wisc.edu]
You should do this homework in groups of two. Please hand in ONE copy of the homework in to the homework7 dropbox at Learn@UW. See the submission guidelines below.
Important Notes:
This homework must be submitted electronically to the Learn@UW dropbox. No hard copies will be accepted. Turn in problems 1-4 as a single PDF document and problems 5 and 6 as .txt files (see the submission guidelines below). List the full names and UWIDs of all members in your group in the PDF document and also in the comment section of your submission.
Submission guidelines:
Please adhere to the following submission guidelines strictly. You will be penalized if your submission violates any of these.
- Submit only one set of files per group to the folder homework7.
- List the full names and UWIDs of all members in your group in the comment section when submitting your files.
- Submit the following files to the dropbox. (The files MUST be named exactly like this):
- hw7_p1-4.pdf - Answers for questions 1-4 in PDF format
- hw7_p5.txt - The assembly code for problem 5
- hw7_p6.txt - The assembly code for problem 6
Submission deadline:
You may submit your files as many times as you want until the end of lecture of your registered section (i.e., 10:45 AM for Section 1 and 3:15 PM for Section 2) on Friday, April 19. After that time we will consider your latest submissions for grading.
Submit problems 1-4 as a single pdf document named "hw7_p1-4.pdf". List the full names and UWIDs of each group member in this file and in the comment section of your dropbox submission.
Problem 1 (4 points)
Load the following program in PennSim and answer the following questions.
.ORIG x3000
LEA R1, STRZ
AND R2, R2, #0
LD R4, CHAR
LOOP LDR R3, R1, #0
BRz DONE
ADD R3, R3, R4
BRnp SKIP
ADD R2, R2, #1
SKIP ADD R1, R1, #1
BR LOOP
DONE ST R2, COUNT
HALT
CHAR .FILL xFFE0
COUNT .FILL x0000
STRZ .STRINGZ "Hello World as always!"
.END
- (1 point) How many times is the instruction at label "LOOP" executed?
- (1 point) How many times is the instruction at label "SKIP" executed?
- (2 points) Describe what this program does in 1-2 sentences.
Problem 2 (4 Points)
Show the symbol table created by the assembler for the following program.
.ORIG x3000
LD R0, LENGTH
AND R1, R1, #0
LEA R2, ARRAY
L00P LDR R3, R2, #0
ADD R1, R1, R0
ADD R2, R2, #1
ADD R0, R0, #-1
BRp L00P
ADD R3, R3, R0
BRz DONE
ST R2, SUM
DONE HALT
LENGTH .FILL x05
ARRAY .BLKW 5
PRSTR .STRINGZ "Done!"
SUM .FILL x0000
.END
Problem 3 (2 points)
The following program is supposed to store the result 4 * R0 at memory address 0x9000. There are two errors in the code. Identify which instructions have an error, and the corresponding type of error.
.ORIG 0x3000
FOURX AND R1, R1, #0
AND R3, R3, #0
ADD R3, R3, #4
LOOP ADD R1, R1, R0
ADD R3, R3, #-1
BRzp LOOP
ST R1, x9000
HALT
.END
Problem 4 (4 Points)
Recall the state machine from homework 4:
The subroutine "FSM" implements the above state machine. The input is stored at the label "INPUT" and the resulting output is stored at the label "OUTPUT". The input bit sequence is read from the most significant bit (MSB) to the least significant bit (LSB). For example, if the content of INPUT was "1011 0011 0110 1000", then the first input bit is 1 and the last input bit is 0. The first output bit is stored as the MSB of OUTPUT, and the last output bit is stored as the LSB. The labels S0, S1, S2, S3 corresponds to states 00, 01, 10, and 11, respectively. Fill in the missing instructions to complete the subroutine.
.ORIG x3000
LEA R0, PROMPT
PUTS
JSR FSM
HALT
FSM ST R0, TMP_R0
ST R1, TMP_R1
ST R2, TMP_R2
ST R3, TMP_R3
LD R0, INPUT
AND R1, R1, 0 ; R1 = output
LEA R2, S0 ; R2 = address of current state
ADD R3, R1, 15
ADD R3, R3, 1 ; R3 = 16
; Loop over all bits
LOOP (a)__________________ ; Determines which state to jump into
S0 ; Output = 0
ADD R0, R0, 0 ; For checking next state
BRzp ST_END ; if MSB(R0) == 0, stay in S0, else S1
LEA R2, S1
BRnzp ST_END
S1 ; Output = 1
(b)__________________
ADD R0, R0, 0 ; For checking next state
BRzp S1_S3 ; if MSB(R0) == 0, go to S3, else S0
LEA R2, S0
BRnzp ST_END
S1_S3 LEA R2, S3
BRnzp ST_END
S2 ; Output = 0
ADD R0, R0, 0 ; For checking next state
BRzp S2_S0 ; if MSB(R0) == 0, go to S0, else S1
LEA R2, S1
BRnzp ST_END
S2_S0 (c)__________________
BRnzp ST_END
S3 ; Output = 1
(d)__________________
ADD R0, R0, 0 ; For checking next state
BRzp S3_S2 ; if MSB(R0) == 0, go to S2, else S0
LEA R2, S0
BRnzp ST_END
S3_S2 LEA R2, S2
ST_END
ADD R1, R1, R1 ; Left shift R1, the temporary result
ADD R0, R0, R0 ; Left shift R0
ADD R3, R3, -1
BRp LOOP
(e)__________________
LD R3, TMP_R3
LD R2, TMP_R2
LD R1, TMP_R1
LD R0, TMP_R0
RET
INPUT .FILL 0
OUTPUT .FILL 0
TMP_R0 .FILL 0
TMP_R1 .FILL 0
TMP_R2 .FILL 0
TMP_R3 .FILL 0
PROMPT .STRINGZ "Modify the value at label INPUT to test the FSM.\n"
.END
Problem 5 (4 points)
It is possible to implement multiplication using less iterations than repeated addition. For instance, multiplying 256 by 256 would require 256 iterations using repeated addition, but only 9 iterations using the below algorithm. The pseudocode below describes the procedure for multiplication of two unsigned 16-bit input values (X, Y) that stores its output as a 16-bit unsigned integer (RESULT). Assume for this problem that X and Y will produce a result that is representable by 16-bits, so do not worry about overflow.
MULTIPLY(X,Y){
a = X // Initialize the two operands
b = Y
res = 0 // Initialize the result
while(b != 0){
if ((b AND 0x01) != 0){
res = res + a
}
a = left_shift(a) // Left shift a by 1 bit
b = right_shift(b) // Right shift b by 1 bit
}
RESULT = res // Store res into RESULT
}
Download the template code for this problem: hw7_p5.txt. DO NOT CHANGE THE LABELS.
Implement the MULTIPLY subroutine as depicted above. You are given the RSH subroutine, which will take the value stored at RSH_IN, right shift it by one bit, and store the result into RSH_RES. Recall that left shifting can be done using addition. Assume the following:
- Your inputs are stored at X and Y.
- Your output should be stored at RESULT.
To test your code use the script, found here. "README.txt" in the zip package contains instructions on how to run the tests and verify your program.
Grading:
Correct result for all test cases: 4 points
Otherwise:
- 1 point for loop that terminates
- 1 point for correct call to RSH
- 1 point for correct implementation of if statement
Problem 6 (12 points)
For this problem you will implement parts of the game Connect Four. The game board is a grid with 7 columns and 6 rows. Each player takes turns selecting a column to place their piece, which lands on the lowest available space in the column. The objective of the game is to be the first player to have four of their pieces connect in a straight line (horizontally, vertically or diagonally).
The game state is stored at several locations in memory. The current player is stored at CURPLYR and the corresponding color is stored at CURCLR. The board is a contiguous chunk of memory starting at BOARD. The state for a certain spot on the board is given by the 16-bit integer located at the address BOARD + 7*ROW + COL, where the leftmost column is column 0, the righmost column is column 6, the bottom row is row 0, and the topmost row is row 5. In other words, the lower left corner is at ROW=0, COL=0. If the value for the location is 0, it is empty. Likewise, if it is 1, player 1 has placed a piece there, and if it is 2, player 2 has placed there.
Example Board |
| Col 0 | Col 1 | Col 2 | Col 3 | Col 4 | Col 5 | Col 6 |
Row 5 | | | | | | | |
Row 4 | | | | | | | |
Row 3 | | | | | | | |
Row 2 | | | | | | | |
Row 1 | | | | | | | |
Row 0 | | 1 | 2 | 2 | 1 | | |
Example Board in Memory |
Address | Value | Comments |
BOARD | 0x0000 | Row = 0, Col = 0, Empty |
BOARD+1 | 0x0001 | Row = 0, Col = 1, Player 1 placed |
BOARD+2 | 0x0002 | Row = 0, Col = 2, Player 2 placed |
BOARD+3 | 0x0002 | Row = 0, Col = 3, Player 2 placed |
BOARD+4 | 0x0001 | Row = 0, Col = 4, Player 1 placed |
BOARD+5 | 0x0000 | Row = 0, Col = 5, Empty |
BOARD+6 | 0x0000 | Row = 0, Col = 6, Empty |
BOARD+7*ROW+COL | 0x0000 | Row = ROW, Col = COL, Empty |
Download the template for this problem: hw7_p6.txt and modify the template according to the tasks below. DO NOT CHANGE THE LABEL NAMES IN THE SUBROUTINES. DO NOT CHANGE THE PROVIDED SUBROUTINES.
We have implemented many of the routines needed for the game. Read through the code at MAIN to get understand the execution flow of the game. You must complete the following subroutines according to the instructions:
- (2 points) CHECKINPUTVALID
- Input in R1: the column as an ASCII character
- Check if the input is a digit; if it is, convert the value into an integer
- Check if the input is 'x' (halts the game)
- Check if the column is in the correct range (0 to 6)
- Output in R1: the column as an integer if valid, -1 if it is not valid, -2 if the character is 'x'
- (2 points) CHECKCOLUMNVALID
- Input in R1: the column as an integer
- DO NOT CHANGE R1
- Check if the column is full. If it is full, return -1 in R2
- If it is not full, find the lowest row in the column and return that in R2
- Output in R2: the row to be updated if the input was valid, or -1 if it was not valid
- (8 points) CHECKEND
- Input in R1: the most recently played column
- Input in R2: the most recently played row
- Input in R3: the current player
- Check for four contiguous pieces in a column (you will implement row and diagonal checking later)
- If we found four contiguous pieces
- Declare the winner using WINMSG
- Change R1, R2 to indicate the game has ended
- If the board is full and no one won
- Declare a tie using TIEMSG
- Change R1, R2 to indicate the game has ended
- Otherwise change the player and color
- Output in R1: The next player ID, or -1 on game end
- Output in R2: The next player's color, or 0 on game end
To test your code use the script, found here. "README.txt" in the zip package contains instructions on how to run the tests and verify your program. There are some changes that you need to make before you are able to run the tests. So make sure you go through the README.txt file.
Tips:
- Make sure your registers are not being overwritten when you call a subroutine (especially R7)
- If you find yourself running out of registers, save them somewhere in memory
- Check all loops for off-by-one errors
- Use Next, Step, and Continue to your advantage!
- If necessary, write helper functions for your code. It may be helpful to break down the program into smaller parts.
- If your code gets too big and gives a PCoffset error, you may need to write "trampoline" code.
Example:
MAIN
JSR TRAMPOLINE
HALT
; At some location within PCoffset range of MAIN
TRAMPOLINE
ST R7, TMP_R7
JSR ROUTINE ; Where ROUTINE is somewhere within PCoffset of
; TRAMPOLINE but outside PCoffset of MAIN
LD R7, TMP_R7
RET
Grading:
CHECKINPUTVALID
- Correct output for all test cases: 2 points
- Otherwise 1 point per test case
- Case 1: correct output on valid input
- Case 2: correct output on invalid input
CHECKCOLUMNVALID
- Correct output for all test cases: 2 points
- Otherwise 1 point per test case
- Case 1: correct output on valid input
- Case 2: correct output on invalid input
CHECKEND
- Correct output for all test cases: 8 points
- Otherwise 2 points per test case
- Case 1: correct output on continuing game (game hasn't ended)
- Case 2: correct output on non-full board win
- Case 3: correct output on full board win
- Case 4: correct output on tie
|