@_@Assembly T_T
Table of contents
Topic description
Nim is a simple two-player game that probably originated in China. There are many types of counters used in the game, such as stones, matches, apples, etc. The game interface is divided into many lines, each with a different number of counters:
line number |
Number of counters |
1 |
○○○ |
2 |
○○○○○○ |
... |
... |
n |
○○○○○○○○○○ |
This experiment made some small changes to the Nim game, as follows: the game interface consists of three lines, and the counter type is stone, of which row A contains 3 stones, row B contains 5 stones, and row C contains 8 stones.
The rules are as follows:
⑴ Each player takes turns removing one or more stones from a row.
⑵ A player cannot remove stones from more than one row in one turn.
(3) When a player removes the last remaining stones from the game interface, the game ends and the player wins.
Require
⑴ At the beginning of the game, you should display the initialization state of the game interface. Specifically: In front of each row of stones, you should output the name of the row, such as "ROW A". You should use the ASCII character lowercase "o" (ASCII code x006F) to represent the stone. The initial state of the game interface should be as follows:
ROW A: ooo
ROW B: ooooo
ROW C: oooooooo
(2) The game always starts with player 1 first, then player 1 and player 2 take turns. At the beginning of each turn, you should output which player's turn it is to start, and prompt the player to take action. For example, for player 1, the following should appear:
Player 1,choose a row and number of rocks:
(3) In order to specify how many stones in a row to remove, the player should enter a letter followed by a number (no need to press Enter after typing), where the letter (A, B or C) specifies the row and the number (from 1 to Number of Stones in Selected Row) specifies the number of stones to remove. Your program must ensure that the player removes a valid number of stones from a valid row. If the player's input is invalid, you should output an error message and prompt the player to enter again. For example, if it's Player 1's turn:
Player 1, choose a row and number of rocks: D4
Invalid move. Try again.
Player 1, choose a row and number of rocks: A9
Invalid move. Try again.
Player 1, choose a row and number of rocks: A*
Invalid move. Try again.
Player 1, choose a row and number of rocks: &4
Invalid move. Try again.
Player 1, choose a row and number of rocks:
Your program should keep prompting the player until the player selects a valid input. Make sure your program can echo the player's input to the screen. When echoing the player's input, it should output a newline character (ASCII code x000A) to point the cursor to the next line.
⑷ After the player selects a valid input, you should check the winner. If a player wins, you should display the corresponding output to indicate that player wins. If there is no winner, your program should update the number of stones per row in the game screen, redisplay the updated game screen, and move on to the next player's turn.
⑸ When a player removes the last stone from the game interface, the game ends. At this point, your program should display the winner and stop. For example, if player 2 removes the last stone, your program should output the following:
Player 2 Wins.
Sample input/output
ROW A: ooo ROW B: ooooo ROW C: oooooooo Player 1, choose a row and number of rocks: B2 ROW A: ooo ROW B: ooo ROW C: oooooooo Player 2, choose a row and number of rocks: A1 ROW A: oo ROW B: ooo ROW C: oooooooo Player 1, choose a row and number of rocks: C6 ROW A: oo ROW B: ooo ROW C: Oh Player 2, choose a row and number of rocks: G1 Invalid move. Try again. Player 2, choose a row and number of rocks: B3 ROW A: oo ROW B: ROW C: Oh Player 1, choose a row and number of rocks: A3 Invalid move. Try again. Player 1, choose a row and number of rocks: C2 ROW A: oo ROW B: ROW C: Player 2, choose a row and number of rocks: A1 ROW A: o ROW B: ROW C: Player 1, choose a row and number of rocks: A* Invalid move. Try again. Player 1, choose a row and number of rocks: &4 Invalid move. Try again. Player 1, choose a row and number of rocks: A1 Player 1 Wins. ----- Halting the processor -----
Tips and Advice
⑴ Remember, all input and output in the program use ASCII characters, you should be responsible for the necessary conversion.
(2) To input characters from the keyboard you should use the TRAP x20 (GETC) command, and in order to echo the typed characters to the screen, you should use the TRAP x21 (OUT) command, which follows the TRAP x20 command.
(3) You should use subroutines when appropriate.
⑷ In each subroutine you write, you should save and restore any registers you use. This will avoid you having problems during debugging.
⑸ During a turn, the player's input must consist of a line designated A, B or C (i.e. capital letters) followed by a number not greater than the number of stones still present in that line.
hint:
① You should set the start address of the program at x3000 (for example, the first line of the program should be .ORIG x3000)
② The source file is named nim.asm
AC code
.orig x3000
again jsr print
jsr datain1
jsr print
jsr datain2
br again
print st r0,save_r0
st r1,save_r1
st r7,save_r7
lea r0,row_a
puts
ld r0,stone
ld r1,num_a
loop_a out
add r1,r1,#-1
brp loop_a
ld r0,cr
out
lea r0,row_b
puts
ld r0,stone
ld r1,num_b
loop_b out
add r1,r1,#-1
brp loop_b
ld r0,cr
out
lea r0,row_c
puts
ld r0,stone
ld r1,num_c
loop_c out
add r1,r1,#-1
brp loop_c
ld r0,cr
out
ld r0,save_r0
ld r1,save_r1
ld r7,save_r7
ret
save_r0 .fill #0
save_r1 .fill #0
stone .fill x006f
cr .fill x000d
row_a .stringz "ROW A: "
row_b .stringz "ROW B: "
row_c .stringz "ROW C: "
num_a .fill #3
num_b .fill #5
num_c .fill #8
cue1 st r0,save_r0
st r7,save_r7
lea r0,play1
puts
ld r0,save_r0
ld r7,save_r7
ret
play1 .stringz "Player 1,choose a row and number of rocks:"
cue2 st r0,save_r0
st r7,save_r7
lea r0,play2
puts
ld r0,save_r0
ld r7,save_r7
ret
play2 .stringz "Player 2,choose a row and number of rocks:"
save_r7 .fill #0
datain1 st r0,save_r0
st r2,save_r2
st r3,save_r3
st r7,saver7
try1 jsr cue1
getc
out
add r2,r0,#0
not r2,r2
add r2,r2,#1
getc
out
add r3,r0,#0
ld r0,lf
out
test1a ld r0,char_a
add r0,r2,r0
brnp test1b
ld r0,char_0
not r0,r0
add r0,r0,#1
add r0,r0,r3
brn error1
ld r3,num_a
not r0,r0
add r0,r0,#1
add r3,r0,r3
brn error1
st r3,num_a
ld r3,sum_abc
add r3,r3,r0
brz win1
st r3,sum_abc
br save
test1b ld r0,char_b
add r0,r2,r0
brnp test1c
ld r0,char_0
not r0,r0
add r0,r0,#1
add r0,r0,r3
brn error1
ld r3,num_b
not r0,r0
add r0,r0,#1
add r3,r0,r3
brn error1
st r3,num_b
ld r3,sum_abc
add r3,r3,r0
brz win1
st r3,sum_abc
br save
test1c ld r0,char_c
add r0,r2,r0
brnp error1
ld r0,char_0
not r0,r0
add r0,r0,#1
add r0,r0,r3
brn error1
ld r3,num_c
not r0,r0
add r0,r0,#1
add r3,r0,r3
brn error1
st r3,num_c
ld r3,sum_abc
add r3,r3,r0
brz win1
st r3,sum_abc
br save
win1 ld r0,lf
out
lea r0,wins1
puts
halt
error1 lea r0,invalid
puts
ld r0,lf
out
br try1
datain2 st r0,save_r0
st r2,save_r2
st r3,save_r3
st r7,saver7
try2 jsr cue2
getc
out
add r2,r0,#0
not r2,r2
add r2,r2,#1
getc
out
add r3,r0,#0
ld r0,lf
out
test2a ld r0,char_a
add r0,r2,r0
brnp test2b
ld r0,char_0
not r0,r0
add r0,r0,#1
add r0,r0,r3
brn error2
ld r3,num_a
not r0,r0
add r0,r0,#1
add r3,r0,r3
brn error2
st r3,num_a
ld r3,sum_abc
add r3,r3,r0
brz win2
st r3,sum_abc
br save
test2b ld r0,char_b
add r0,r2,r0
brnp test2c
ld r0,char_0
not r0,r0
add r0,r0,#1
add r0,r0,r3
brn error2
ld r3,num_b
not r0,r0
add r0,r0,#1
add r3,r0,r3
brn error2
st r3,num_b
ld r3,sum_abc
add r3,r3,r0
brz win2
st r3,sum_abc
br save
test2c ld r0,char_c
add r0,r2,r0
brnp error2
ld r0,char_0
not r0,r0
add r0,r0,#1
add r0,r0,r3
brn error2
ld r3,num_c
not r0,r0
add r0,r0,#1
add r3,r0,r3
brn error2
st r3,num_c
ld r3,sum_abc
add r3,r3,r0
brz win2
st r3,sum_abc
br save
win2 ld r0,lf
out
lea r0,wins2
puts
halt
error2 lea r0,invalid
puts
ld r0,lf
out
br try2
save ld r0,lf
out
ld r0,saver0
ld r2,save_r2
ld r3,save_r3
ld r7,saver7
ret
lf .fill x000a
char_a .fill x0041
char_b .fill x0042
char_c .fill x0043
char_0 .fill x0030
wins1 .stringz "Player 1 Wins."
wins2 .stringz "Player 2 Wins."
invalid .stringz "Invalid move. Try again."
sum_abc .fill #16
saver0 .fill #0
save_r2 .fill #0
save_r3 .fill #0
saver7 .fill #0
.end
Thought analysis
overall program design
core data structure
1. Display the game page
First store the value of the register into the memory, and then store the value of the memory into the register after the sub-function completes the task, use the pseudo operation .stringz to open up memory to store strings, and set the number of stones in Row A, Row B and Row C Also stored in memory.
First use the LEA instruction to store the first address of the string into R0, then output it through PUTS, use the LD instruction to store the ascll code of the character o into R0, and then use the LD instruction to store the number of stones into R1, R1 as a counter, use OUT The character o is output in a loop, and finally the ascll code of the newline character is stored in R0 with the LD instruction, and output with OUT.
2. User operation
(1) Output prompt
Use the pseudo operation .stringz to store the prompt string in the memory, first store the values of the registers R0 and R7 used in the memory, and then use the LEA instruction to store the first address of the string in R0, and use PUTS to output the prompt, Then restore the values of R0 and R7.
(2) User input
Use GETC to read the first input data, and then use OUT to echo, ADD command to transfer the data of R0 into R2, then use NOT to invert R2, ADD adds one to R2, that is, negative R2, and then use GETC to read Take the second input data, OUT echoes it, and the ADD instruction transfers the data of R0 into R3.
(3) Determine whether the data is valid
Use the pseudo operation .fill to store the ascll codes of characters A, B and C into the memory, use the LD instruction to store the ascll codes of the corresponding characters into R0, and then use the ADD instruction to add the result of R0 and R2 to R0, by judging whether R0 is It is 0 to judge whether it is A, B, C or invalid input.
(4) Take the stone
Use the LD instruction to store the ascll code of character 0 into R0, then negate R0, and store the result of the addition with R3 into R0, then use the LD instruction to store the number of stones into R3, negate R0, and compare with R3. The result of the addition is stored in R3, and finally the value of R3 is stored in the memory.
Algorithm flow
1. Display the game page
2. Player operation