|
†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 6×6 snakes game of one player. The final program is less than 200 lines. The purpose of this exercise is to get students ready for assembly programming and the second exercise, playing a snakes game. |
|
|
Rules of a Snakes Game
It is a board game for two players who take turns in drawing segments of a snake. The last player able to move wins. The game is played on a grid; 6×6 is a good size. The above game is played on a matrix of 5×5 dots. The first player, Blue (top), starts in the second row and column, and the other player, Red (bottom), starts in the last but one row and column, as shown by the blue and red squares. The players take turns in growing a snake, extending it a segment at a time by drawing a horizontal or vertical line from the previous dot to an adjacent dot. Each player must avoid touching either his/her opponent’s snake or his/her own snake. The first player unable to move loses. |
[/0-z].
‘/’: 15%)
Start a new game after asking the user to pick y or n.
[0-z]: 20%)
For example, if the first move of the player X is k, the boards are displayed as follows:
. . . . . . ⇒ 0 1 2 3 4 5
. . . . . . ⇒ 6 7 8 9 a b
. . . . . . ⇒ c d e f g h
. . . . . . ⇒ i j k l m n
. . . . . . ⇒ o p q r s t
. . . . . . ⇒ u v w x y z
⇓ X at k
. . . . . . ⇒ 0 1 2 3 4 5
. . . . . . ⇒ 6 7 8 9 a b
. . . . . . ⇒ c d e f g h
. . X . . . ⇒ i j k l m n
. . . . . . ⇒ o p q r s t
. . . . . . ⇒ u v w x y z
g, the boards are displayed as follows:
. . . . . . ⇒ 0 1 2 3 4 5
. . . . . . ⇒ 6 7 8 9 a b
. $ $ X . . ⇒ c d e f g h
. . O . . . ⇒ i j k l m n
. . + . . . ⇒ o p q r s t
. . + . . . ⇒ u v w x y z
⇓ X at g
. . . . . . ⇒ 0 1 2 3 4 5
. . . . . . ⇒ 6 7 8 9 a b
. $ $ $ X . ⇒ c d e f g h
. . O . . . ⇒ i j k l m n
. . + . . . ⇒ o p q r s t
. . + . . . ⇒ u v w x y z
. . . . . . ⇒ 0 1 2 3 4 5
. . . . . . ⇒ 6 7 8 9 a b
. . . . . . ⇒ c d e f g h
. . . . . . ⇒ i j k l m n
. . . . . . ⇒ o p q r s t
. . . . . . ⇒ u v w x y z
the instructor uses the following string:
board: .ascii "\n\n . . . . . . 0 1 2 3 4 5"
.ascii "\n . . . . . . 6 7 8 9 a b"
.ascii "\n . . . . . . c d e f g h"
.ascii "\n . . . . . . i j k l m n"
.ascii "\n . . . . . . o p q r s t"
.asciiz "\n . . . . . . u v w x y z\n"
Also, the instructor uses the following command to represent the offsets:
offset: .half 6, 8, 10, 12, 14, 16
.half 39, 41, 43, 45, 47, 49
.half 72, 74, 76, 78, 80, 82
.half 105, 107, 109, 111, 113, 115
.half 138, 140, 142, 144, 146, 148
.half 171, 173, 175, 177, 179, 181
where
$t0, the following code then puts the piece X at that location:
mul $t0, $t0, 2 # Each offset is two-byte long.
lh $t1, offset($t0) # Load $t1 with the offset of the index $t0.
li $t2, 'X' # Put the piece ‘X’ in $t2.
sb $t2, board($t1) # Put the piece at the location, board+offset.
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 $ra
where 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.
|
|
#
######################### Marking the Game Board #########################
#
.data
pr1: .asciiz "\nStart Marking a Snakes Game Board."
pr2: .asciiz "\nEnter X's next move [/0..z]: "
pr3: .asciiz "\nEnter O's next move [/0..z]: "
player: .byte 'X' # current player
mov: .byte ' ' # current move
last_X: .byte ' ' # last move of X
last_O: .byte ' ' # last move of O
board: .ascii "\n\n . . . . . . 0 1 2 3 4 5"
.ascii "\n . . . . . . 6 7 8 9 a b"
.ascii "\n . . . . . . c d e f g h"
.ascii "\n . . . . . . i j k l m n"
.ascii "\n . . . . . . o p q r s t"
.asciiz "\n . . . . . . u v w x y z\n"
offset: .half 6, 8, 10, 12, 14, 16
.half 39, 41, 43, 45, 47, 49
.half 72, 74, 76, 78, 80, 82
.half 105, 107, 109, 111, 113, 115
.half 138, 140, 142, 144, 146, 148
.half 171, 173, 175, 177, 179, 181
.text
.globl main
#
####################### Main Program #######################
#
main:
la $a0, pr1 # Greeting
li $v0, 4
syscall
la $a0, board # Game board
li $v0, 4
syscall
L0: lb $v0, player # $v0 = current player
beq $v0, 'O', L1
la $a0, pr2 # X's next move
li $v0, 4
syscall
li $t0, 'O' # $t0 = 'O'
j L2
L1: la $a0, pr3 # Y's next move
li $v0, 4
syscall
li $t0, 'X' # $t0 = 'X'
L2: li $v0, 12
syscall
sb $v0, mov # mov = $v0, next move
beq $v0, '/', L3
move $a0, $v0
jal MarkBoard # Mark the move.
sb $t0, player
j L0
L3: li $v0, 10 # End of program
syscall
#
####################### Mark the board. #######################
#
# Input: $a0 (the char move [0-z])
# Output: the updated board
MarkBoard:
subu $sp, $sp, 4
sw $ra, ($sp) # Push the return address, $ra.
subu $sp, $sp, 4 # Decrement the $sp to make space for $t0.
sw $t0, ($sp) # Push the $t0.
# Mark the board.
jal FindIndex
lh $t1, offset($t0)
lb $t2, player # $t2 = current player
sb $t2, board($t1)
# Change the marker.
beq $t2, 'O', L21
lb $t0, last_X
sb $a0, last_X
li $t2, '$'
j L22
L21: lb $t0, last_O
sb $a0, last_O
li $t2, '+'
L22: move $a0, $t0
jal FindIndex
lh $t1, offset($t0)
sb $t2, board($t1)
la $a0, board
li $v0, 4
syscall
lw $t0, ($sp) # Pop $t0.
addu $sp, $sp, 4 # Increment the $sp.
lw $ra, ($sp) # Pop the return address, $ra.
addu $sp, $sp, 4
jr $ra
#
####################### Find the Index of Offset. #######################
#
# Input: $a0 (the char move [0-z])
# Output: $t0 (the integer index)
FindIndex:
subu $sp, $sp, 4
sw $ra, ($sp) # Push the return address, $ra.
subu $sp, $sp, 4 # Decrement the $sp to make space for $a0.
sw $a0, ($sp) # Push the $a0.
bgt $a0, '9', L31
sub $a0, $a0, '0'
j L32
L31: sub $a0, $a0, 'a'
add $a0, $a0, 10
L32: mul $t0, $a0, 2
lw $a0, ($sp) # Pop $a0.
addu $sp, $sp, 4 # Increment the $sp.
lw $ra, ($sp) # Pop the return address, $ra.
addu $sp, $sp, 4
jr $ra # Return.
|
|
|
|
|
|
|
|
| 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 | .half |
Allocating space for a half word (two bytes) | |
| 7 | .space n |
Allocating n bytes of space |
|
| 8 | .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 | bgt rs, rt, label |
if rs>rt then goto label |
Branch if greater than |
| 5 | blt rs, rt, label |
if rs<rt then goto label |
Branch if less than |
| 6 | bne rs, rt, label |
if rs≠rt then goto label |
Branch if not equal to |
| 7 | j label |
jump to label |
Jump |
| 8 | jal label |
jump to label and save the return address in $31 or $ra |
Jump and link |
| 9 | jr rs |
jump to [rs]; [ ]: contents of |
Jump and link |
| 10 | la rd, mem |
rd = address( mem ) |
Load address |
| 11 | lb rd, mem |
rd = mem |
Load byte |
| 12 | lh rd, mem |
rd = mem |
Load half word |
| 13 | li rd, imm |
rd = imm |
Load immediate |
| 14 | lw rd, mem |
rd = mem |
Load word |
| 15 | mul rd, rs, rt |
rd = rs × rt |
Multiply |
| 16 | sb rs, mem |
mem = rs |
Store byte |
| 17 | sub rd, rs, rt |
rd = rs - rt |
Subtract |
| 18 | subu rd, rs, rt |
rd = rs - rt (no overflow) |
Subtract unsigned |
| 19 | sw rs, mem |
mem = rs |
Store word |
| 20 | 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 |
|
“We used to play spin the bottle when I was a kid,” says comedy writer Gene Perret. “A girl would spin the bottle pointed to you when it stopped, the girl could either kiss you or give you a nickel. By the time I was 14, I owned my own house.” |