Soft Due Date† and Submission Method On or before Thursday, February 15, 2024 and upload the source code (no documentation needed) to the section of “COVID-19 Exams, Homeworks, & Programming Exercises” of Blackboard. †Since related topics may not be covered completely by the due date, no penalty will be applied if submitted after the due date. However, you may lag behind if you are not able to submit it by then. In addition, the Exam I will cover the materials from the Programming Exercise I. Objective Design and implement a MIPS assembly program, which displays a tic-tac-toe game of one player. The final program is about 100 lines, most of which are for I/O. The purpose of this exercise is to get students ready for assembly programming and the second exercise, playing a tic-tac-toe game. |
| | 1|2|3 ----- ----- | | 4|5|6 ----- ----- | | 7|8|9
| | 1|2|3 ----- ----- |x| 4|5|6 ----- ----- | | 7|8|9
| | 1|2|3 ----- ----- | | 4|5|6 ----- ----- | | 7|8|9the instructor uses the following string:
board: .ascii "\n | | 1|2|3\n ----- -----" .ascii "\n | | 4|5|6\n ----- -----" .asciiz "\n | | 7|8|9\n" # (offset) 0 123456789012345678901 23456789012345678901where the numbers are offsets (not assembly code) and the new line, ‘\n’, is one byte long. The offset of the move (1-9),
$a0
, is found by using the following formula:
offset = $a0×2 + 3 + [($a0-1)÷3]×36For example, if the move is 5, the offset is
5×2+3+[(5-1)÷3]×36=13+1×36=49
lw $t0, offset # Load $t0 with the offset. li $t1, 'x' # Load $t1 with the marker 'x'. sb $t1, board($t0) # Store the marker to the location, board+offset.Assuming the game just started, the game board will be as follows after entering the move 5:
| | 1|2|3 | | 1|2|3 ----- ----- ----- ----- | | 4|5|6 ⇒ |x| 4|5|6 ----- ----- ----- ----- | | 7|8|9 | | 7|8|9
routine1
is given as follows:
jal routine1 # Jump and link to routine1 next: ...where the label
next
is not required.
The following command in the subroutine routine1
will return the control back to the next
, the next command after the jal routine1
”:routine1: ... jr $ra # Jump to the contents of $rawhere the return address is saved in the register
$31
or $ra
$31
or $ra
, has to be saved before making the call.
The return address is restored after the called subroutine returns.
The instructor uses the runtime stack to save the return addresses, so deep subroutine calls are supported.
Use the following two commands to push the $ra
to the runtime stack:
subu $sp, $sp, 4 # Decrement the $sp to make space for $ra. sw $ra, ($sp) # Push the return address, $ra.and use the following two commands to pop up the
$ra
from the runtime stack:
lw $ra, ($sp) # Pop the return address, $ra. addu $sp, $sp, 4 # Increment the $sp.You may also use the runtime stack to save the register and variable values.
|
|
# ######################### Mark the Game Board ######################### # .data prompt: .asciiz "\nEnter the next move (1..9): " board: .ascii "\n | | 1|2|3\n ----- -----" .ascii "\n | | 4|5|6\n ----- -----" .asciiz "\n | | 7|8|9\n" .text .globl main # ########################## Main Program ####################### # main: li $t0, 3 # Mark 3 moves only. la $a0, board li $v0, 4 # Print the game board. syscall L1: # Beginning of a loop la $a0, prompt li $v0, 4 syscall # Print the prompt. # Read the next move. li $v0, 5 # Read a move (1..9). syscall # The syscall 5 is read an integer. move $a0, $v0 # a0: the move in integer jal MarkMove # Call the subroutine MarkMove. la $a0, board li $v0, 4 # Print the game board. syscall sub $t0, $t0, 1 # Decrease the counter $t0 by 1. bnez $t0, L1 # If not end of loop, go to L1. # Closing up li $v0, 10 # Exit. syscall # ######################### Mark a Move ######################### # # Input: $a0 (the move in integer, 1..9) # Output: the game board marked MarkMove: # Save data in the runtime stack. subu $sp, $sp, 4 # Decrement the $sp to make space for $ra. sw $ra, ($sp) # Push/save the return address, $ra. # Find the offset $v0 = a0x2+3+[(a0-1)/3]x36 jal GetOffset # Call the subroutine MarkMove. li $t1, 'x' # Put the piece ‘x’ in $t1. sb $t1, board($v0) # Put the piece at the location, board+offset. # Restore the data from the runtime stack. lw $ra, ($sp) # Pop/restore the return address, $ra. addu $sp, $sp, 4 # Increment the $sp. jr $ra # Return. # ######################### Get the Offset ######################### # # Input: $a0 (the move in integer, 1..9) # Output: $v0 (the offset of the marker in the board) GetOffset: # Save data in the runtime stack. subu $sp, $sp, 4 # Decrement the $sp to make space for $ra. sw $ra, ($sp) # Push/save the return address, $ra. subu $sp, $sp, 4 # Decrement the $sp to make space for $t0. sw $t0, ($sp) # Push/save the $t0. subu $sp, $sp, 4 # Decrement the $sp to make space for $t1. sw $t1, ($sp) # Push/save the $t1. # Find the offset $v0 = a0x2+3+[(a0-1)/3]x36 mul $t0, $a0, 2 add $t0, $t0, 3 move $t1, $a0 sub $t1, $t1, 1 div $t1, $t1, 3 mul $t1, $t1, 36 add $v0, $t0, $t1 # Restore the data from the runtime stack. lw $t1, ($sp) # Pop/restore $t1. addu $sp, $sp, 4 # Increment the $sp. lw $t0, ($sp) # Pop/restore $t0. addu $sp, $sp, 4 # Increment the $sp. lw $ra, ($sp) # Pop/restore the return address, $ra. addu $sp, $sp, 4 # Increment the $sp. jr $ra # Return. |
|
|
Start Showing a One-Player Tic-Tac-Toe Game. | | 1|2|3 ----- ----- | | 4|5|6 ----- ----- | | 7|8|9 Enter the next move (1-9): 4 | | 1|2|3 ----- ----- x| | 4|5|6 ----- ----- | | 7|8|9 Continue? (y/n) y Enter the next move (1-9): 3 | |o 1|2|3 ----- ----- x| | 4|5|6 ----- ----- | | 7|8|9 Continue? (y/n) y Enter the next move (1-9): 8 | |o 1|2|3 ----- ----- x| | 4|5|6 ----- ----- |x| 7|8|9 Continue? (y/n) n New game? (y/n) y Start Showing a One-Player Tic-Tac-Toe Game. | | 1|2|3 ----- ----- | | 4|5|6 ----- ----- | | 7|8|9 Enter the next move (1-9): 6 | | 1|2|3 ----- ----- | |x 4|5|6 ----- ----- | | 7|8|9 Continue? (y/n) y Enter the next move (1-9): 1 o| | 1|2|3 ----- ----- | |x 4|5|6 ----- ----- | | 7|8|9 Continue? (y/n) n New game? (y/n) n -- program is finished running -- |
No. | Directive | Description | |
---|---|---|---|
1 | .ascii "string" |
Allocating space for string | |
2 | .asciiz "string" |
Allocating space for string, NULL terminated | |
3 | .byte |
Allocating space for a byte | |
4 | .data |
Beginning of data section | |
5 | .globl name |
Making the following name be a global symbol | |
6 | .space n |
Allocating n bytes of space |
|
7 | .text |
Beginning of text section | |
No. | Instruction | Operation | Description |
1 | add rd, rs, rt |
rd = rs + rt |
Add;rd : destination register, rs : first source register, and rt : second source register or immediate value.Check MIPS Registers and Usage Convention. |
2 | addu rd, rs, rt |
rd = rs + rt (no overflow) |
Add unsigned |
3 | beq rs, rt, label |
if rs==rt then goto label |
Branch if equal to |
4 | blt rs, rt, label |
if rs<rt then goto label |
Branch if less than |
5 | div rd, rs, rt |
rd = rs ÷ rt |
Divide |
6 | j label |
jump to label |
Jump |
7 | la rd, mem |
rd = address( mem ) |
Load address |
8 | lb rd, mem |
rd = mem |
Load byte |
9 | li rd, imm |
rd = imm |
Load immediate |
10 | lw rd, mem |
rd = mem |
Load word |
11 | mul rd, rs, rt |
rd = rs × rt |
Multiply |
12 | sb rs, mem |
mem = rs |
Store byte |
13 | sub rd, rs, rt |
rd = rs - rt |
Subtract |
14 | subu rd, rs, rt |
rd = rs - rt (no overflow) |
Subtract unsigned |
15 | sw rs, mem |
mem = rs |
Store word |
16 | syscall |
|
System call; check System Services. |
Service | Code in $v0 |
Arguments | Result |
---|---|---|---|
print_int | 1 | $a0 = integer to be printed |
|
print_float | 2 | $f12 = float to be printed |
|
print_double | 3 | $f12 = double to be printed |
|
print_string | 4 | $a0 = address of string in memory |
|
read_int | 5 | integer returned in $v0 |
|
read_float | 6 | float returned in $v0 |
|
read_double | 7 | double returned in $v0 |
|
read_string | 8 | $a0 = address of string input buffer$a1 = length of string buffer (n ) |
|
malloc | 9 | $a0 = amount |
address in $v0 |
exit | 10 | ||
print character | 11 | $a0 = character to be printed |
|
read character | 12 | character returned in $v0 |