Design and implement a MIPS assembly program, which displays a 2×2 dot-and-box game of one player.
The final program is about 100 lines without using subroutines.
The purpose of this exercise is to get students ready for assembly programming and the second exercise, playing a dot-and-box game against computer.
![]() An example of a 2×2 dot-and-box game |
. . . . 0 . 1 . 2 3 4 . . . . 5 . 6 . 7 8 9 . . . . a . b . (board) (index)
. . . . 0 . 1 . . . . . 0 . 1 . 2 3 4 2 3 4 . . . . 5 . 6 . ⇒ . . . . 5 . 6 . 7 8 9 8 | 7 8 9 . . . . a . b . . . . . a . b . (board) (index) (board) (index)
. . . . 0 . 1 . 2 3 4 . . . . 5 . 6 . 7 8 9 . . . . a . b . (board) (index)the instructor uses the following strings to represent the game board and index:
board: .ascii "\n\n . . . . 0 . 1 ." .ascii "\n 2 3 4" .ascii "\n . . . . 5 . 6 ." .ascii "\n 7 8 9" .asciiz "\n . . . . a . b .\n"The assembly code annotated with the corresponding offsets is given as follows:
board: .ascii "\n\n . . . . 0 . 1 ." offset = 0 1234567890123456789012345678 .ascii "\n 2 3 4" offset = 28 + 1234567890123456789012345678 .ascii "\n . . . . 5 . 6 ." offset = 56 + 1234567890123456789012345678 .ascii "\n 7 8 9" offset = 84 + 1234567890123456789012345678 .asciiz "\n . . . . a . b .\n" offset = 112 + 1234567890123456789012345678 9where the numbers are offsets (not assembly code) and the new line, ‘\n’, is one byte long. The instructor uses the following two commands to represent the offsets and markers, respectively:
offset: .byte 6, 8, 33, 35, 37, 62, 64, 89, 91, 93, 118, 120 marker: .byte '-', '-', '|', '|', '|', '-', '-', '|', '|', '|', '-', '-'Convert the indexes a and b to 10 and 11, respectively. Assuming the integer move, 0-11 (or 0-9 a-b), is stored in
$t0
, the following code then puts the marker at that location:
lb $t1, offset($t0) # Load $t1 with the offset of the index $t0. lb $t2, marker($t0) # Find the corresponding marker. sb $t2, board($t1) # Put the marker at the location, board+offset.For example, if the first move is 8 stored in
$t0
and the above code is executed, the board is displayed as follows:
. . . . 0 . 1 . . . . . 0 . 1 . 2 3 4 2 3 4 . . . . 5 . 6 . ⇒ . . . . 5 . 6 . 7 8 9 8 | 7 8 9 . . . . a . b . . . . . a . b . (board) (index) (board) (index)
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.
|
|
# ######################### Marking the Game Board ######################### # .data pr1: .asciiz "\n********** Marking the game board ********** board: .ascii "\n\n . . . . 0 . 1 ." .ascii "\n 2 3 4" .ascii "\n . . . . 5 . 6 ." .ascii "\n 7 8 9" .asciiz "\n . . . . a . b .\n" pr2: .asciiz "\nEnter an move: [0-9] " offset: .byte 6, 8, 33, 35, 37, 62, 64, 89, 91, 93, 118, 120 marker: .byte '-', '-', '|', '|', '|', '-', '-', '|', '|', '|', '-', '-' .text .globl main # ########################## Main Program ####################### # main: # Printing the prompt 1 la $a0, pr1 li $v0, 4 # 4: printing string syscall # Printing the game board la $a0, board li $v0, 4 # 4: printing string syscall # Printing the prompt 2 la $a0, pr2 li $v0, 4 # 4: printing string syscall # Reading the move li $v0, 5 # 5: reading integer (no a or b) syscall move $a0, $v0 # a0: the integer move jal MarkMove # Calling the subroutine MarkMove # Printing the game board la $a0, board li $v0, 4 # 4: printing string syscall # Closing up li $v0, 10 # 10: exiting syscall # ######################### Mark a Move ######################### # # Input: $a0 (the integer move 0-9) # Output: MarkMove: subu $sp, $sp, 4 # Decrement the $sp to make space for $ra. 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. lb $t0, offset($a0) # Load $t0 with the offset of the index $a0. lb $t1, marker($a0) # Find the corresponding marker. sb $t1, board($t0) # Put the marker at the location, board+offset. lw $t0, ($sp) # Pop $t0. addu $sp, $sp, 4 # Increment the $sp. lw $ra, ($sp) # Pop the return address, $ra. addu $sp, $sp, 4 # Increment the $sp. jr $ra # Return. |
|
|
|
|
|
|
Start Showing a One-Player 2x2 Dot-and-Box Game. . . . . 0 . 1 . 2 3 4 . . . . 5 . 6 . 7 8 9 . . . . a . b . Enter the next move (0..b): 8 . . . . 0 . 1 . 2 3 4 . . . . 5 . 6 . | 7 8 9 . . . . a . b . Continue? (y/n) y . . . . 0 . 1 . 2 3 4 . . . . 5 . 6 . | 7 8 9 . . . . a . b . Enter the next move (0..b): b . . . . 0 . 1 . 2 3 4 . . . . 5 . 6 . | 7 8 9 . .-. . a . b . Continue? (y/n) y . . . . 0 . 1 . 2 3 4 . . . . 5 . 6 . | 7 8 9 . .-. . a . b . Enter the next move (0..b): 0 .-. . . 0 . 1 . 2 3 4 . . . . 5 . 6 . | 7 8 9 . .-. . a . b . Continue? (y/n) n New game? (y/n) y Start Showing a One-Player 2x2 Dot-and-Box Game. . . . . 0 . 1 . 2 3 4 . . . . 5 . 6 . 7 8 9 . . . . a . b . Enter the next move (0..b): 5 . . . . 0 . 1 . 2 3 4 .-. . . 5 . 6 . 7 8 9 . . . . a . b . Continue? (y/n) y . . . . 0 . 1 . 2 3 4 .-. . . 5 . 6 . 7 8 9 . . . . a . b . Enter the next move (0..b): 2 . . . . 0 . 1 . | 2 3 4 .-. . . 5 . 6 . 7 8 9 . . . . a . b . 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 | .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 | j label |
jump to label |
Jump |
7 | jal label |
jump to label and save the return address in $31 or $ra |
Jump and link |
8 | jr rs |
jump to [rs] ; [ ]: contents of |
Jump and link |
9 | la rd, mem |
rd = address( mem ) |
Load address |
10 | lb rd, mem |
rd = mem |
Load byte |
11 | lh rd, mem |
rd = mem |
Load half word |
12 | li rd, imm |
rd = imm |
Load immediate |
13 | lw rd, mem |
rd = mem |
Load word |
14 | mul rd, rs, rt |
rd = rs × rt |
Multiply |
15 | sb rs, mem |
mem = rs |
Store byte |
16 | sub rd, rs, rt |
rd = rs - rt |
Subtract |
17 | subu rd, rs, rt |
rd = rs - rt (no overflow) |
Subtract unsigned |
18 | sw rs, mem |
mem = rs |
Store word |
19 | 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.” |