|
†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 one-player, 6×6 SOS game. The final program is around 150 lines without counting the declarations of data structures. The purpose of this exercise is to get students ready for assembly programming and the second exercise, playing an SOS game. |
|
| The object of the game is for each player to attempt to create the straight sequence S-O-S among connected squares (either diagonally, horizontally, or vertically), and to create as many such sequences as they can. If a player succeeds in creating an SOS, that player immediately takes another turn, and continues to do so until no SOS can be created on their turn. Otherwise turns alternate between players after each move. Keeping track of who made which SOSs can be done by, e.g., one player circling their SOSs and the other player drawing a line through theirs. Once the grid has been filled up, the winner is the player who made the most SOSs. If the grid is filled up and the number of SOSs for each player is the same, then the game is a draw. |
. . . . . . ⇒ 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
k, the board is 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
⇓ S at k
. . . . . . ⇒ 0 1 2 3 4 5
. . . . . . ⇒ 6 7 8 9 a b
. . . . . . ⇒ c d e f g h
. . S . . . ⇒ 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 ‘S’ 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, 'S' # Put the piece ‘S’ in $t2.
sb $t2, board($t1) # Put the piece at the location, board+offset.
board(n) = 'S'
board(t) = 'O'
board(z) = 'S'
‡Note that the instructor has tried his best to make the list complete, but could not 100% guarantee its correctness or completeness.
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.
|
|
#
# Checking an SOS
#
.data
p1: .asciiz "\n\nStart Checking an SOS."
p2: .asciiz "\nEnter the next move: [0..z] "
p3: .asciiz "\nNumber of SOSs: "
board: .ascii "\n\n . . . . . . 0 1 2 3 4 5"
.ascii "\n . . . . . . 6 7 8 9 a b"
.ascii "\n . . S O . . 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
SOS: .ascii "012" # 0
.ascii "07e" # 1
.ascii "06c" # 2
.ascii "123" # 3
.ascii "18f" # 4
.ascii "17d" # 5
.ascii "234" # 6
.ascii "29g" # 7
.ascii "28e" # 8
.ascii "27c" # 9
.ascii "345" # 10
.ascii "3ah" # 11
.ascii "39f" # 12
.ascii "38d" # 13
.ascii "4ag" # 14
.ascii "49e" # 15
.ascii "5bh" # 16
.ascii "5af" # 17
.ascii "678" # 18
.ascii "6dk" # 19
.ascii "6ci" # 20
.ascii "789" # 21
.ascii "7el" # 22
.ascii "7dj" # 23
.ascii "89a" # 24
.ascii "8fm" # 25
.ascii "8ek" # 26
.ascii "8di" # 27
.ascii "9ab" # 28
.ascii "9gn" # 29
.ascii "9fl" # 30
.ascii "9ej" # 31
.ascii "agm" # 32
.ascii "afk" # 33
.ascii "bhn" # 34
.ascii "bgl" # 35
.ascii "cde" # 36
.ascii "cjq" # 37
.ascii "cio" # 38
.ascii "def" # 39
.ascii "dkr" # 40
.ascii "djp" # 41
.ascii "efg" # 42
.ascii "els" # 43
.ascii "ekq" # 44
.ascii "ejo" # 45
.ascii "fgh" # 46
.ascii "fmt" # 47
.ascii "flr" # 48
.ascii "fkp" # 49
.ascii "gms" # 50
.ascii "glq" # 51
.ascii "hnt" # 52
.ascii "hmr" # 53
.ascii "ijk" # 54
.ascii "ipw" # 55
.ascii "iou" # 56
.ascii "jkl" # 57
.ascii "jqx" # 58
.ascii "jpv" # 59
.ascii "klm" # 60
.ascii "kry" # 61
.ascii "kqw" # 62
.ascii "kpu" # 63
.ascii "lmn" # 64
.ascii "lsz" # 65
.ascii "lrx" # 66
.ascii "lqv" # 67
.ascii "msy" # 68
.ascii "mrw" # 69
.ascii "ntz" # 70
.ascii "nsx" # 71
.ascii "opq" # 72
.ascii "pqr" # 73
.ascii "qrs" # 74
.ascii "rst" # 75
.ascii "uvw" # 76
.ascii "vwx" # 77
.ascii "wxy" # 78
.ascii "xyz" # 79
.text
.globl main
#
########################## Main Program #######################
#
main:
# Print the Prompt p1, greeting.
la $a0, p1
li $v0, 4
syscall
# Print the board.
la $a0, board
li $v0, 4
syscall
# Read the next move.
la $a0, p2
li $v0, 4
syscall
li $v0, 12
syscall
# Check the move.
blt $v0, '0', L1
bgt $v0, '9', L1
sub $t0, $v0, '0'
j L2
L1: sub $t0, $v0, 'a'
add $t0, $t0, 10
# Mark the board.
L2: 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, 'S' # Put the piece ‘S’ in $t2.
sb $t2, board($t1) # Put the piece at the location, board+offset.
la $a0, board
li $v0, 4
syscall
move $t0, $0 # $t0: SOS index [0..239] where 239 = 3*80 - 1
move $t1, $0 # $t1: SOS range [0..79]
move $t2, $0 # $t2: SOS #
# Checking 'S'
L3: lb $a0, SOS($t0)
jal C2I
mul $t3, $a0, 2
lh $t4, offset($t3)
lb $t3, board($t4)
beq $t3, 'S', L4
add $t0, $t0, 2
j L6
# Checking 'O'
L4: add $t0, $t0, 1
lb $a0, SOS($t0)
jal C2I
mul $t3, $a0, 2
lh $t4, offset($t3)
lb $t3, board($t4)
beq $t3, 'O', L5
add $t0, $t0, 1
j L6
# Checking 'S'
L5: add $t0, $t0, 1
lb $a0, SOS($t0)
jal C2I
mul $t3, $a0, 2
lh $t4, offset($t3)
lb $t3, board($t4)
bne $t3, 'S', L6
add $t2, $t2, 1 # An SOS found
# Checking next SOS
L6: add $t0, $t0, 1
add $t1, $t1, 1
ble $t1, 79, L3
# Print the SOS #.
la $a0, p3
li $v0, 4
syscall
move $a0, $t2
li $v0, 1
syscall
# End of program
End: li $v0, 10
syscall
#
############## Convert character [0..z] to integer [0..35]. ##################
#
# Input: $a0 (character [0..z])
# Output: $a0 (integer [0..35])
# Comment: The runtime stack is not needed.
#
C2I:
subu $sp, $sp, 4 # Decrement the $sp to make space for $ra.
sw $ra, ($sp) # Push the return address, $ra.
blt $a0, '0', L10
bgt $a0, '9', L10
sub $a0, $a0, '0'
j L11
L10: sub $a0, $a0, 'a'
add $a0, $a0, 10
lw $ra, ($sp) # Pop the return address, $ra.
addu $sp, $sp, 4 # Increment the $sp.
L11: jr $ra
|
|
|
|
|
|
|
|
| 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 | ble rs, rt, label |
if rs≤rt then goto label |
Branch if less than or equal to |
| 6 | blt rs, rt, label |
if rs<rt then goto label |
Branch if less than |
| 7 | bne rs, rt, label |
if rs≠rt then goto label |
Branch if not equal to |
| 8 | j label |
jump to label |
Jump |
| 9 | jal label |
jump to label and save the return address in $31 or $ra |
Jump and link |
| 10 | jr rs |
jump to [rs]; [ ] contents of |
Jump and link |
| 11 | la rd, mem |
rd = address( mem ) |
Load address |
| 12 | lb rd, mem |
rd = mem |
Load byte |
| 13 | lh rd, mem |
rd = mem |
Load half word |
| 14 | li rd, imm |
rd = imm |
Load immediate |
| 15 | lw rd, mem |
rd = mem |
Load word |
| 16 | move rd, rs |
rd = rs |
Move register |
| 17 | mul rd, rs, rt |
rd = rs × rt |
Multiply |
| 18 | sb rs, mem |
mem = rs |
Store byte |
| 19 | sub rd, rs, rt |
rd = rs - rt |
Subtract |
| 20 | subu rd, rs, rt |
rd = rs - rt (no overflow) |
Subtract unsigned |
| 21 | sw rs, mem |
mem = rs |
Store word |
| 22 | 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 |