实验要求 本实验需要在LC-3中实现简易版四子棋的游戏,两位选手通过键盘和输出窗口轮流交互操作,棋盘由6 X 6的网格组成。 游戏规则如下: 两位选手依次轮流落子; 选手不能悔棋; 有子的地方不能继续落子; 直到有一方的四个棋子能够连成一条水平线、垂直线或者是对角线; 如果棋盘已满,无人获胜,则平局。 游戏最初时应该打印空的棋盘,可以用ASCII码"-" (即ASCII 码 x002D)来表示该处为空,"O"(ASCII 码 x004F)表示第一位选手的棋子,"X" (ASCII 码 x0058)来表示第二位选手的棋子,为了让棋盘更易于观察,在各列间加一个空格,第6列之后不要添加,初始棋盘应该如下: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 选手一始终先下第一步棋,然后两者轮流落子,在每次落子之后,应该打印该选手的信息,提示他落子,以选手一为例,应该打印信息如下: Player 1, choose a column: 为了明确选手的落子的位置,该选手应该输入数字1-6,然后回车,数字1-6指示在落子所在的列,从左到右,无需输入行号,程序应默认从行号6到行号1递减的顺序填入该棋子,若前后输入的列号相同,则行号减一。例如,如果选手第一次在左起第二列落子,应该输入2,然后回车,则该棋子落在行6列2处,当后面输入的列号再次为2时,则将棋子落子行5列2处,以此类推,详情见后续示例输出。程序应该确保选手输入的数字对应正确的列的范围,如果输入不合理,应该输出一条错误信息,提示该选手继续输入,例如,如果对于选手一: Player 1, choose a column: D Invalid move. Try again. Player 1, choose a column: 7 Invalid move. Try again. Player 1, choose a column: 程序应该一直提示该选手,知道输入正确的数字,当用户输入完成,程序应通过显示回馈给选手,然后通过换行符(ASCII 码 x000A)换行。 当选手输入成功后,程序应打印更新后的棋盘,并检查是否有人获胜,如果没人获胜,则轮到下一位输入。 当其中一位获胜或平局时,游戏结束,程序显示最后的棋盘情况并终止(Halt)。例如,如果选手二有四子相连,应该输出: Player 2 Wins. 如果平局,程序应该输出: Tie Game. 示例输出 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Player 1, choose a column: 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - O - - - - - Player 2, choose a column: 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - O X - - - - Player 1, choose a column: 2 - - - - - - - - - - - - - - - - - - - - - - - - - O - - - - O X - - - - Player 2, choose a column: 3 - - - - - - - - - - - - - - - - - - - - - - - - - O - - - - O X X - - - Player 1, choose a column: 3 - - - - - - - - - - - - - - - - - - - - - - - - - O O - - - O X X - - - Player 2, choose a column: 1 - - - - - - - - - - - - - - - - - - - - - - - - X O O - - - O X X - - - Player 1, choose a column: 4 - - - - - - - - - - - - - - - - - - - - - - - - X O O - - - O X X O - - Player 2, choose a column: 4 - - - - - - - - - - - - - - - - - - - - - - - - X O O X - - O X X O - - Player 1, choose a column: 3 - - - - - - - - - - - - - - - - - - - - O - - - X O O X - - O X X O - - Player 2, choose a column: 4 - - - - - - - - - - - - - - - - - - - - O X - - X O O X - - O X X O - - Player 1, choose a column: 4 - - - - - - - - - - - - - - - O - - - - O X - - X O O X - - O X X O - - Player 1 Wins. ----- Halting the processor ----- 提示: 参考程序在内存中分配36个空间来表示棋盘的每个位置,最简单的遍历棋盘的方法为:如果该位置为空,则存放0,如果该位置为选手一的棋子,则存放1,如果为选手二的棋子,则存放-1,这样可以最大程度的使用状态码。 记得所有的输入和输出使用ASCII字符,必要时自己转换。 从键盘接收输入时使用TRAP x20 (GETC),显示字符时使用TRAP x20 和TRAP x21 (OUT),合适的地方使用子例程,每次子例程都应暂存和恢复要使用的寄存器,这样有利于调试程序。 程序首行指定第一条指令的地址,即.ORIG x3000。 最后提交的文件为connect4.asm,并提交试验报告。 现场考核要求讲解设计哪些子程序和相应的功能以及你是怎么判定赢方的算法。 实验思路 在地址X3500处开辟一个36大小的连续空间来存储棋盘数据 该四子棋主要目标是设计子程序,通过一直循环让用户1和用户2不断下棋,直到和棋或有一方获胜(四点连成一条横线或一条竖线或一条斜线) 设计的子程序: 输出初始化棋盘init 检查用户1输入是否合理IsCorrect1 检查用户2输入是否合理IsCorrect2 输出棋盘print 判断棋盘是否已满IsFull 判断用户1是否赢了比赛(竖)IsSHU1 判断用户2是否赢了比赛(竖)IsSHU2 判断用户1是否赢了比赛(横)IsLine1 判断用户2是否赢了比赛(横)IsLine2 判断用户1或用户2是否赢了比赛(斜1) 判断用户1或用户2是否赢了比赛(斜2) 判断用户1或用户2是否赢了比赛(斜3) 判断用户1或用户2是否赢了比赛(斜4) 判定赢方的算法 若有一方赢,那么肯定由他最新输入的棋子决定。即他输入前肯定没赢,输入后有四子连成一条直线。由此分了六种判定情况:
从用户最新下棋的地址开始,往上查询四颗棋子,若超出棋盘顶部,则没有四子连线。 若有四颗棋子的地址所存的数值同为1或-1,则当前输入的用户获胜。往上查询完往下查询,同理。 2.四点连成一条横线 提前定义了数据区域左半棋盘的地址,代表该点要往右查询四颗棋子。 不在这个数据区域则代表该点要往左查询四颗棋子。 左半棋盘则是只能由最新输入的棋子地址开始往右查询四子,右半棋盘则是只能往左查询四子。若有四颗棋子的地址所存的数值同为1或-1,则当前输入的用户获胜。 3.四点连成一条斜线(1) 提前定义了数据区域左上角棋盘的地址,代表该点要往右下查询四颗棋子。 不在这个数据区域则返回false 4.四点连成一条斜线(2) 提前定义了数据区域右下角棋盘的地址,代表该点要往左上查询四颗棋子。 不在这个数据区域则返回false 5.四点连成一条斜线(3) 提前定义了数据区域右上角棋盘的地址,代表该点要往左下查询四颗棋子。 不在这个数据区域则返回false 6.四点连成一条斜线(4) 提前定义了数据区域左下角棋盘的地址,代表该点要往右上查询四颗棋子。 不在这个数据区域则返回false 汇编代码实现子函数: 初始化棋盘init 打印棋盘 提示用户1和用户2下棋,并判断用户输入是否合理 数据定义区 检查用户2输入是否合理IsCorrect2 判断棋盘是否已满IsFull 判断用户1是否赢了比赛(竖)IsSHU1 判断用户2是否赢了比赛(竖)IsSHU2 判断用户1或用户2是否赢了比赛(斜1) 判断用户1或用户2是否赢了比赛(斜2) 判断用户1或用户2是否赢了比赛(斜3) 判断用户1或用户2是否赢了比赛(斜4) Ps: 在实验过程中发现在指令加载标签地址时有时候偏移量已经超限,只能将标签定义在离该指令比较近的地方,导致有些标签名字较为奇怪。同时由于标签不能重名,也出现了很多奇怪的名字……另外由于我子程序重用部分有点多,导致别人400多行代码能解决的实验我写了1000行…………(泪目) |
.ORIG X3000 ;
;初始化空白棋盘init
LD R3,DATA ;指向开辟数据区的首地址
LD R2,SIX ;R2作为初始化六行的计数器
ADD R2,R2,#1 ;
LOOPOUT0 LD R1,SIX ;R1作为初始化六列的计数器
ADD R2,R2,#-1 ;
BRp LOOPIN0 ;R2>0,继续循环
BRz NEXT0 ;循环结束,来到下一部分
LOOPIN0 AND R4,R4,#0 ;
STR R4,R3,#0 ;棋盘初始化为0
ADD R3,R3,#1 ;
ADD R1,R1,#-1 ;
BRp LOOPIN0 ;
BRz LOOPOUT0 ;
NEXT0 JSR PRINT ;打印空白棋盘
Input JSR IsFull ;判断棋盘是否满了(和局)
ADD R0,R0,#0 ;
BRp END ;
JSR Iscorrect1 ;提示用户1输入并判断输入是否正确,返回用户输入的棋子坐标
JSR PRINT ;打印用户1下棋后的棋盘
JSR IsSHU1 ;
ADD R6,R6,#0 ;
BRp END ;
JSR IsLine1 ;
ADD R6,R6,#0 ;
BRp END ;
AND R6,R6,#0 ;
ADD R6,R6,#1 ;
JSR IsXie1 ;
ADD R6,R6,#0 ;
BRp END ;
AND R6,R6,#0 ;
ADD R6,R6,#1 ;
JSR IsXie2 ;
ADD R6,R6,#0 ;
BRp END ;
AND R6,R6,#0 ;
ADD R6,R6,#1 ;
JSR IsXie3 ;
ADD R6,R6,#0 ;
BRp END ;
AND R6,R6,#0 ;
ADD R6,R6,#1 ;
JSR IsXie4 ;
ADD R6,R6,#0 ;
BRp END ;
LD R0,BLANKLINE ;
TRAP X21 ;
JSR Iscorrect2 ;提示用户2输入并判断输入是否正确,返回用户输入的棋子坐标
JSR PRINT ;
JSR IsSHU2 ;
ADD R6,R6,#0 ;
BRp END ;
JSR IsLine2 ;
ADD R6,R6,#0 ;
BRp END ;
AND R6,R6,#0 ;
ADD R6,R6,#-1 ;
JSR IsXie1 ;
ADD R6,R6,#0 ;
BRp END ;
AND R6,R6,#0 ;
ADD R6,R6,#-1 ;
JSR IsXie2 ;
ADD R6,R6,#0 ;
BRp END ;
AND R6,R6,#0 ;
ADD R6,R6,#-1 ;
JSR IsXie3 ;
ADD R6,R6,#0 ;
BRp END ;
AND R6,R6,#0 ;
ADD R6,R6,#-1 ;
JSR IsXie4 ;
ADD R6,R6,#0 ;
BRp END ;
LD R0,BLANKLINE ;
TRAP X21 ;
BRnzp Input ;
END HALT
SIX .fill x0006 ;
BLANK .fill x0020 ;
BLANKLINE .fill x000A ;
LINE .fill x002D ;
user1 .stringz "Player 1, choose a column:" ;
user2 .stringz "Player 2, choose a column:" ;
Wrong .stringz "Invalid move. Try again." ;
Ascii0 .fill x0030 ;
Ascii6 .fill x0036 ;
DATA .FILL x3500 ;开辟一个50大小的空间来存储棋盘数据
DATAEND .fill x351E ;
CHARO .fill x004F ;
CHARX .fill x0058 ;
SAVER0 .BLKW 1 ;
SAVER1 .BLKW 1 ;
SAVER2 .BLKW 1 ;
SAVER3 .BLKW 1 ;
SAVER4 .BLKW 1 ;
SAVER5 .BLKW 1 ;
SAVER6 .BLKW 1 ;
SAVER7 .BLKW 1 ;
ASCII .fill -48 ;
;打印棋盘
PRINT ST R0,SAVER0 ;
ST R1,SAVER1 ;
ST R2,SAVER2 ;
ST R3,SAVER3 ;
ST R4,SAVER4 ;
ST R7,SAVER7 ;
LD R3,DATA ;R3装载数据区首地址
LD R2,SIX ;R2作为输出六行的计数器
ADD R2,R2,#1 ;
LOOPOUT LD R1,SIX ;R1作为输出六列的计数器
LD R0,BLANKLINE ;
TRAP X21 ;输出换行符
ADD R2,R2,#-1 ;
BRp LOOPIN ;R2>0,继续循环
BRz FINISH ;循环结束,来到下一部分
LOOPIN LDR R4,R3,#0 ;R4装在数据区首地址的值
BRz LOADLINE ;如果R4=0,输出"-"
BRp LOADO ;如果R4>0,输出"O"
BRn LOADX ;如果R4<0,输出"X"
LOADLINE LD R0,LINE ;
TRAP x21 ;输出"-"
ADD R3,R3,#1 ;
BRnzp NEXTPART ;
LOADO LD R0,CHARO ;
TRAP X21 ;输出"O"
ADD R3,R3,#1 ;
BRnzp NEXTPART ;
LOADX LD R0,CHARX ;
TRAP X21 ;输出"X"
ADD R3,R3,#1 ;
BRnzp NEXTPART ;
NEXTPART LD R0,BLANK ;
TRAP X21 ;输出空格
ADD R1,R1,#-1 ;
BRp LOOPIN ;
BRz LOOPOUT ;
FINISH LD R0,SAVER0 ;
LD R1,SAVER1 ;
LD R2,SAVER2 ;
LD R3,SAVER3 ;
LD R4,SAVER4 ;
LD R7,SAVER7 ;
RET
;判断用户1输入是否合理,即用户落子的列在1-6之间
Iscorrect1 ST R1,SAVER1 ;
ST R2,SAVER2 ;
ST R7,SAVER7 ;
ST R3,SAVER3 ;
ST R5,SAVER5 ;
BRnzp NEXTPART1 ;
WrongInput1 LD R0,BLANKLINE ;
TRAP X21 ;
LEA R0,Wrong ;
PUTS ;
LD R0,BLANKLINE ;
TRAP X21 ;
NEXTPART1 LEA R0,user1 ;
PUTS ;提示用户1落子
TRAP X23 ;用户输入落子的列
LD R1,Ascii0 ;
NOT R1,R1 ;
ADD R1,R1,#1 ;
ADD R2,R0,R1 ;
BRnz WrongInput1 ;用户输入<1,重新输入
LD R2,Ascii6 ;
NOT R2,R2 ;
ADD R2,R2,#1 ;
ADD R1,R0,R2 ;
BRp WrongInput1 ;用户输入>6,重新输入
TRAP X21 ;回显用户输入
LD R6,ASCII ;
ADD R0,R0,R6 ;进行用户的输入Ascii的转换
LD R3,DATAEND ;
ADD R3,R3,R0 ;
ADD R3,R3,#-1 ;R3指向用户输入的列的第6行
IsNull1 LDR R4,R3,#0 ;判断该点处的状态
BRz Change1 ;
BRnp LastLine1 ;
Change1 ADD R0,R3,#0 ;
AND R4,R4,#0 ;
ADD R4,R4,#1 ;
STR R4,R3,#0 ;
BRnzp Done1 ;
LastLine1 ADD R3,R3,#-6 ;
LDR R4,R3,#0 ;
BRnp LastLine1 ;
LD R5,DATA ;
NOT R5,R5 ;
ADD R5,R5,#1 ;
ADD R5,R3,R5 ;
BRn WrongInput1 ;
ADD R0,R3,#0 ;
AND R4,R4,#0 ;
ADD R4,R4,#1 ;
STR R4,R3,#0 ;
Done1 LD R1,SAVER1 ;
LD R2,SAVER2 ;
LD R7,SAVER7 ;
LD R3,SAVER3 ;
LD R4,SAVER4 ;
LD R5,SAVER5 ;
RET
;判断棋盘是否已经满了(和局)
IsFull ST R1,SAVER1 ;
ST R2,SAVER2 ;
ST R3,SAVER3 ;
ST R4,SAVER4 ;
ST R7,SAVER7 ;
LD R3,DATA ;指向开辟数据区的首地址
LD R2,SIX ;R2作为六行的计数器
ADD R2,R2,#1 ;
LOOPOUT1 LD R1,SIX ;R1作为六列的计数器
ADD R2,R2,#-1 ;
BRp LOOPIN1 ;R2>0,继续循环
BRz Full ;循环结束,来到下一部分
LOOPIN1 LDR R4,R3,#0 ;
BRz NotFull ;
ADD R3,R3,#1 ;
ADD R1,R1,#-1 ;
BRp LOOPIN1 ;
BRz LOOPOUT1 ;
Full AND R0,R0,#0 ;
ADD R0,R0,#1 ;
BRnzp DONE ;
NotFull AND R0,R0,#0 ;
BRnzp DONE ;
DONE LD R1,SAVER1 ;
LD R2,SAVER2 ;
LD R3,SAVER3 ;
LD R4,SAVER4 ;
LD R7,SAVER7 ;
RET
;判断用户2输入是否合理,即用户落子的列在1-6之间
Iscorrect2 ST R1,SAVER1 ;
ST R2,SAVER2 ;
ST R7,SAVER7 ;
ST R3,SAVER3 ;
ST R5,SAVER5 ;
BRnzp NEXTPART2 ;
WrongInput2 LD R0,BLANKLINE ;
TRAP X21 ;
LEA R0,Wrong ;
PUTS ;
LD R0,BLANKLINE ;
TRAP X21 ;
NEXTPART2 LEA R0,user2 ;
PUTS ;提示用户2落子
TRAP X23 ;用户输入落子的列
LD R1,Ascii0 ;
NOT R1,R1 ;
ADD R1,R1,#1 ;
ADD R2,R0,R1 ;
BRnz WrongInput2 ;用户输入<1,重新输入
LD R2,Ascii6 ;
NOT R2,R2 ;
ADD R2,R2,#1 ;
ADD R1,R0,R2 ;
BRp WrongInput2 ;用户输入>6,重新输入
TRAP X21 ;回显用户输入
LD R6,ASCII ;
ADD R1,R0,R6 ;进行用户的输入Ascii的转换
LD R3,DATAEND ;
ADD R3,R3,R1 ;
ADD R3,R3,#-1 ;R3指向用户输入的列的第6行
IsNull2 LDR R4,R3,#0 ;判断该点处的状态
BRz ChangeN1 ;
BRnp LastLine2 ;
ChangeN1 ADD R0,R3,#0 ;
AND R4,R4,#0 ;
ADD R4,R4,#-1 ;
STR R4,R3,#0 ;
BRnzp Done2 ;
LastLine2 ADD R3,R3,#-6 ;
LDR R4,R3,#0 ;
BRnp LastLine2 ;
LD R5,DATA ;
NOT R5,R5 ;
ADD R5,R5,#1 ;
ADD R5,R3,R5 ;
BRn WrongInput2 ;
ADD R0,R3,#0 ;
AND R4,R4,#0 ;
ADD R4,R4,#-1 ;
STR R4,R3,#0 ;
Done2 LD R1,SAVER1 ;
LD R2,SAVER2 ;
LD R7,SAVER7 ;
LD R3,SAVER3 ;
LD R5,SAVER5 ;
RET
;判断用户1是否赢了比赛(竖)
IsSHU1 ST R1,SR1 ;
ST R2,SR2 ;
ST R3,SR3 ;
ST R4,SR4 ;
ST R7,SR7 ;
ST R0,SR0 ;
ST R5,SR5 ;
AND R4,R4,#0 ;
AND R6,R6,#0 ;
LD R3,SR0 ;
LD R1,NFOUR ;
SHU1 LDR R2,R3,#0 ;
BRp A1 ;
BRnz FINISH1 ;
A1 ADD R4,R4,#1 ;
ADD R2,R4,R1 ;
BRz WIN1 ;
ADD R3,R3,#6 ;
LD R5,DATAend ;
NOT R5,R5 ;
ADD R5,R5,#1 ;
ADD R5,R3,R5 ;
BRnz SHU1 ;
BRp FINISH1 ;
WIN1 LEA R0,U1WIN ;
PUTS ;
ADD R6,R6,#1 ;
BRnzp FINISH1 ;
FINISH1 LD R1,SR1 ;
LD R2,SR2 ;
LD R3,SR3 ;
LD R4,SR4 ;
LD R7,SR7 ;
LD R0,SR0 ;
LD R5,SR5 ;
RET
;判断用户2是否赢了比赛(竖)
IsSHU2 ST R1,SR1 ;
ST R2,SR2 ;
ST R3,SR3 ;
ST R4,SR4 ;
ST R7,SR7 ;
ST R0,SR0 ;
ST R5,SR5 ;
AND R4,R4,#0 ;
AND R6,R6,#0 ;
LD R3,SR0 ;
LD R1,NFOUR ;
SHU2 LDR R2,R3,#0 ;
BRn A2 ;
BRzp FINISH2 ;
A2 ADD R4,R4,#1 ;
ADD R2,R4,R1 ;
BRz WIN2 ;
ADD R3,R3,#6 ;
LD R5,DATAend ;
NOT R5,R5 ;
ADD R5,R5,#1 ;
ADD R5,R3,R5 ;
BRnz SHU2 ;
BRp FINISH2 ;
WIN2 LEA R0,U2WIN ;
PUTS ;
ADD R6,R6,#1 ;
BRnzp FINISH2 ;
FINISH2 LD R1,SR1 ;
LD R2,SR2 ;
LD R3,SR3 ;
LD R4,SR4 ;
LD R7,SR7 ;
LD R0,SR0 ;
LD R5,SR5 ;
RET
FOUR .fill x0004 ;
NFOUR .fill #-4 ;
U1WIN .stringz "Player 1 Wins." ;
U2WIN .stringz "Player 2 Wins." ;
SR0 .BLKW 1 ;
SR1 .BLKW 1 ;
SR2 .BLKW 1 ;
SR3 .BLKW 1 ;
SR4 .BLKW 1 ;
SR5 .BLKW 1 ;
SR6 .BLKW 1 ;
SR7 .BLKW 1 ;
Data .fill x351E ;
DATAend .fill x3523 ;
;判断是否用户1是否赢了比赛(横)
IsLine1 ST R1,SR1 ;
ST R2,SR2 ;
ST R3,SR3 ;
ST R4,SR4 ;
ST R7,SR7 ;
ST R0,SR0 ;
ST R5,SR5 ;
AND R5,R5,#0 ;
AND R6,R6,#0 ;
LEA R1,RIGHT ;
R LDR R4,R1,#0 ;
NOT R2,R4 ;
ADD R2,R2,#1 ;
ADD R2,R2,R0 ;
BRz right ;
ADD R1,R1,#1 ;
ADD R5,R5,#1 ;
LD R2,Eighteen ;
ADD R2,R5,R2 ;
BRz left ;
BRnp R ;
right AND R5,R5,#0 ;
LD R4,FOUR ;
LD R3,SR0 ;
LD R1,NFOUR ;
HENG1 LDR R2,R3,#0 ;
BRp Add1 ;
BRnz Finish1 ;
Add1 ADD R5,R5,#1 ;
ADD R2,R5,R1 ;
BRz WIN1 ;
ADD R4,R4,#-1 ;
BRz Finish1 ;
ADD R3,R3,#1 ;
BRp HENG1 ;
left AND R5,R5,#0 ;
LD R4,FOUR ;
LD R3,SR0 ;
LD R1,NFOUR ;
HENG2 LDR R2,R3,#0 ;
BRp Add2 ;
BRnz Finish1 ;
Add2 ADD R5,R5,#1 ;
ADD R2,R5,R1 ;
BRz WIN1 ;
ADD R4,R4,#-1 ;
BRz Finish1 ;
ADD R3,R3,#-1 ;
BRp HENG2 ;
Win1 LEA R0,U1WIN ;
PUTS ;
ADD R6,R6,#1 ;
BRnzp Finish1 ;
Finish1 LD R1,SR1 ;
LD R2,SR2 ;
LD R3,SR3 ;
LD R4,SR4 ;
LD R7,SR7 ;
LD R0,SR0 ;
LD R5,SR5 ;
RET
;判断是否用户2是否赢了比赛(横)
IsLine2 ST R1,SR1 ;
ST R2,SR2 ;
ST R3,SR3 ;
ST R4,SR4 ;
ST R7,SR7 ;
ST R0,SR0 ;
ST R5,SR5 ;
AND R5,R5,#0 ;
AND R6,R6,#0 ;
LEA R1,RIGHT ;
r LDR R4,R1,#0 ;
NOT R2,R4 ;
ADD R2,R2,#1 ;
ADD R2,R2,R0 ;
BRz right2 ;
ADD R1,R1,#1 ;
ADD R5,R5,#1 ;
LD R2,Eighteen ;
ADD R2,R5,R2 ;
BRz left2 ;
BRnp r ;
right2 AND R5,R5,#0 ;
LD R4,FOUR ;
LD R3,SR0 ;
LD R1,NFOUR ;
Heng1 LDR R2,R3,#0 ;
BRn Add3 ;
BRzp Finish2 ;
Add3 ADD R5,R5,#1 ;
ADD R2,R5,R1 ;
BRz WIN2 ;
ADD R4,R4,#-1 ;
BRz Finish2 ;
ADD R3,R3,#1 ;
BRp Heng1 ;
left2 AND R5,R5,#0 ;
LD R4,FOUR ;
LD R3,SR0 ;
LD R1,NFOUR ;
HENG4 LDR R2,R3,#0 ;
BRn Add4 ;
BRzp Finish2 ;
Add4 ADD R5,R5,#1 ;
ADD R2,R5,R1 ;
BRz WIN2 ;
ADD R4,R4,#-1 ;
BRz Finish2 ;
ADD R3,R3,#-1 ;
BRp HENG4 ;
Win2 LEA R0,U2WIN ;
PUTS ;
ADD R6,R6,#1 ;
BRnzp Finish2 ;
Finish2 LD R1,SR1 ;
LD R2,SR2 ;
LD R3,SR3 ;
LD R4,SR4 ;
LD R7,SR7 ;
LD R0,SR0 ;
LD R5,SR5 ;
RET
RIGHT .fill x3500 ;
.fill x3501 ;
.fill x3502 ;
.fill x3506 ;
.fill x3507 ;
.fill x3508 ;
.fill x350C ;
.fill x350D ;
.fill x350E ;
.fill x3512 ;
.fill x3513 ;
.fill x3514 ;
.fill x3518 ;
.fill X3519 ;
.fill X351A ;
.fill x351E ;
.fill x351F ;
.fill x3520 ;
Eighteen .fill #-18 ;
;判断是否用户1或用户2是否赢了比赛(斜1)
IsXie1 ST R1,S1 ;
ST R2,S2 ;
ST R3,S3 ;
ST R4,S4 ;
ST R7,S7 ;
ST R0,S0 ;
ST R5,S5 ;
ST R6,S6 ;
AND R5,R5,#0 ;
AND R6,R6,#0 ;
LEA R1,XIEDATA ;
X LDR R4,R1,#0 ;
NOT R2,R4 ;
ADD R2,R2,#1 ;
ADD R2,R2,R0 ;
BRz XIE ;
ADD R1,R1,#1 ;
ADD R5,R5,#1 ;
ADD R2,R5,#-9 ;
BRz FinishXIE1 ;
BRnp X ;
XIE LD R2,S6 ;
BRp XIE1 ;
BRn XIE2 ;
XIE1 AND R5,R5,#0 ;
LD R4,FOUR ;
LD R3,S0 ;
LD R1,NFOUR ;
xie1 LDR R2,R3,#0 ;
BRp jia1 ;
BRnz FinishXIE1 ;
jia1 ADD R5,R5,#1 ;
ADD R2,R5,R1 ;
BRz win1 ;
ADD R4,R4,#-1 ;
BRz FinishXIE1 ;
ADD R3,R3,#7 ;
BRp xie1 ;
XIE2 AND R5,R5,#0 ;
LD R4,FOUR ;
LD R3,SR0 ;
LD R1,NFOUR ;
xie2 LDR R2,R3,#0 ;
BRn jia2 ;
BRzp FinishXIE1 ;
jia2 ADD R5,R5,#1 ;
ADD R2,R5,R1 ;
BRz win2 ;
ADD R4,R4,#-1 ;
BRz FinishXIE1 ;
ADD R3,R3,#7 ;
BRp xie2 ;
win1 ADD R6,R6,#1 ;
LEA R0,U1WIN ;
PUTS ;
BRnzp FinishXIE1 ;
win2 ADD R6,R6,#1 ;
LEA R0,U2WIN ;
PUTS ;
BRnzp FinishXIE1 ;
FinishXIE1 LD R1,S1 ;
LD R2,S2 ;
LD R3,S3 ;
LD R4,S4 ;
LD R7,S7 ;
LD R0,S0 ;
LD R5,S5 ;
RET
XIEDATA .fill x3500 ;
.fill x3501 ;
.fill x3502 ;
.fill x3506 ;
.fill x3507 ;
.fill x3508 ;
.fill x350C ;
.fill x350D ;
.fill x350E ;
;判断是否用户1或用户2是否赢了比赛(斜2)
IsXie2 ST R1,S1 ;
ST R2,S2 ;
ST R3,S3 ;
ST R4,S4 ;
ST R7,S7 ;
ST R0,S0 ;
ST R5,S5 ;
ST R6,S6 ;
AND R5,R5,#0 ;R5作为判断四个点中有多少个符合条件的点的计数器
AND R6,R6,#0 ;R6作为是否赢了的状态码,0则没赢,1则赢
LEA R1,XIEDATA2 ;R1指向要往左上寻找的数组的首地址
XX LDR R4,R1,#0 ;
NOT R2,R4 ;
ADD R2,R2,#1 ;
ADD R2,R2,R0 ;
BRz xie ;
ADD R1,R1,#1 ;
ADD R5,R5,#1 ;
ADD R2,R5,#-9 ;
BRz Finishxie1 ;
BRnp XX ;
xie LD R2,S6 ;
BRp xiE1 ;
BRn xiE2 ;
xiE1 AND R5,R5,#0 ;
LD R4,Four ;
LD R3,S0 ;
LD R1,NFour ;
xie11 LDR R2,R3,#0 ;
BRp Jia1 ;
BRnz FinishXIE1 ;
Jia1 ADD R5,R5,#1 ;
ADD R2,R5,R1 ;
BRz wiN1 ;
ADD R4,R4,#-1 ;
BRz Finishxie1 ;
ADD R3,R3,#-7 ;
BRp xie11 ;
xiE2 AND R5,R5,#0 ;
LD R4,Four ;
LD R3,S0 ;
LD R1,NFour ;
xie22 LDR R2,R3,#0 ;
BRn Jia2 ;
BRzp FinishXIE1 ;
Jia2 ADD R5,R5,#1 ;
ADD R2,R5,R1 ;
BRz wiN2 ;
ADD R4,R4,#-1 ;
BRz Finishxie1 ;
ADD R3,R3,#-7 ;
BRp xie22 ;
wiN1 ADD R6,R6,#1 ;
LEA R0,U1win ;
PUTS ;
BRnzp Finishxie1 ;
wiN2 ADD R6,R6,#1 ;
LEA R0,U2win ;
PUTS ;
BRnzp Finishxie1 ;
Finishxie1 LD R1,S1 ;
LD R2,S2 ;
LD R3,S3 ;
LD R4,S4 ;
LD R7,S7 ;
LD R0,S0 ;
LD R5,S5 ;
RET
;该数组是棋盘右下角,要往左上查询四个点
XIEDATA2 .fill x3515 ;
.fill x3516 ;
.fill x3117 ;
.fill x351B ;
.fill x351C ;
.fill x351D ;
.fill x3521 ;
.fill x3522 ;
.fill x3523 ;
Four .fill x0004 ;
NFour .fill #-4 ;
U1win .stringz "Player 1 Wins." ;
U2win .stringz "Player 2 Wins." ;
S0 .BLKW 1 ;
S1 .BLKW 1 ;
S2 .BLKW 1 ;
S3 .BLKW 1 ;
S4 .BLKW 1 ;
S5 .BLKW 1 ;
S6 .BLKW 1 ;
S7 .BLKW 1 ;
;判断是否用户1或用户2是否赢了比赛(斜3)
IsXie3 ST R1,S1 ;
ST R2,S2 ;
ST R3,S3 ;
ST R4,S4 ;
ST R7,S7 ;
ST R0,S0 ;
ST R5,S5 ;
ST R6,S6 ;
AND R5,R5,#0 ;
AND R6,R6,#0 ;
LEA R1,XIEDATA3 ;
xxx LDR R4,R1,#0 ;
NOT R2,R4 ;
ADD R2,R2,#1 ;
ADD R2,R2,R0 ;
BRz xiee ;
ADD R1,R1,#1 ;
ADD R5,R5,#1 ;
ADD R2,R5,#-9 ;
BRz FinishXIE3 ;
BRnp xxx ;
xiee LD R2,S6 ;
BRp Xiee1 ;
BRn Xiee2 ;
Xiee1 AND R5,R5,#0 ;
LD R4,Four ;
LD R3,S0 ;
LD R1,NFour ;
xie111 LDR R2,R3,#0 ;
BRp JIa1 ;
BRnz FinishXIE3 ;
JIa1 ADD R5,R5,#1 ;
ADD R2,R5,R1 ;
BRz WIn1 ;
ADD R4,R4,#-1 ;
BRz FinishXIE3 ;
ADD R3,R3,#5 ;
BRp xie111 ;
Xiee2 AND R5,R5,#0 ;
LD R4,Four ;
LD R3,S0 ;
LD R1,NFour ;
xie222 LDR R2,R3,#0 ;
BRn JIa2 ;
BRzp FinishXIE3 ;
JIa2 ADD R5,R5,#1 ;
ADD R2,R5,R1 ;
BRz WIn2 ;
ADD R4,R4,#-1 ;
BRz FinishXIE3 ;
ADD R3,R3,#5 ;
BRp xie222 ;
WIn1 ADD R6,R6,#1 ;
LEA R0,U1win ;
PUTS ;
BRnzp FinishXIE3 ;
WIn2 ADD R6,R6,#1 ;
LEA R0,U2win ;
PUTS ;
BRnzp FinishXIE3 ;
FinishXIE3 LD R1,S1 ;
LD R2,S2 ;
LD R3,S3 ;
LD R4,S4 ;
LD R7,S7 ;
LD R0,S0 ;
LD R5,S5 ;
RET
;该数组是棋盘右上角,要往左下查询四个点
XIEDATA3 .fill x3503 ;
.fill x3504 ;
.fill x3505 ;
.fill x3509 ;
.fill x350A ;
.fill x350B ;
.fill x350F ;
.fill x3510 ;
.fill x3511 ;
;判断是否用户1或用户2是否赢了比赛(斜4)
IsXie4 ST R1,S1 ;
ST R2,S2 ;
ST R3,S3 ;
ST R4,S4 ;
ST R7,S7 ;
ST R0,S0 ;
ST R5,S5 ;
ST R6,S6 ;
AND R5,R5,#0 ;
AND R6,R6,#0 ;
LEA R1,XIEDATA4 ;
xxxx LDR R4,R1,#0 ;
NOT R2,R4 ;
ADD R2,R2,#1 ;
ADD R2,R2,R0 ;
BRz xiee1 ;
ADD R1,R1,#1 ;
ADD R5,R5,#1 ;
ADD R2,R5,#-9 ;
BRz FinishXIE4 ;
BRnp xxxx ;
xiee1 LD R2,S6 ;
BRp Xiee11 ;
BRn Xiee22 ;
Xiee11 AND R5,R5,#0 ;
LD R4,Four ;
LD R3,S0 ;
LD R1,NFour ;
xie1111 LDR R2,R3,#0 ;
BRp JIa11 ;
BRnz FinishXIE4 ;
JIa11 ADD R5,R5,#1 ;
ADD R2,R5,R1 ;
BRz WIn11 ;
ADD R4,R4,#-1 ;
BRz FinishXIE4 ;
ADD R3,R3,#-5 ;
BRp xie1111 ;
Xiee22 AND R5,R5,#0 ;
LD R4,Four ;
LD R3,S0 ;
LD R1,NFour ;
xie2222 LDR R2,R3,#0 ;
BRn JIa22 ;
BRzp FinishXIE4 ;
JIa22 ADD R5,R5,#1 ;
ADD R2,R5,R1 ;
BRz WIn22 ;
ADD R4,R4,#-1 ;
BRz FinishXIE4 ;
ADD R3,R3,#-5 ;
BRp xie2222 ;
WIn11 ADD R6,R6,#1 ;
LEA R0,U1win ;
PUTS ;
BRnzp FinishXIE4 ;
WIn22 ADD R6,R6,#1 ;
LEA R0,U2win ;
PUTS ;
BRnzp FinishXIE4 ;
FinishXIE4 LD R1,S1 ;
LD R2,S2 ;
LD R3,S3 ;
LD R4,S4 ;
LD R7,S7 ;
LD R0,S0 ;
LD R5,S5 ;
RET
;该数组是棋盘左下角,要往右上查询四个点
XIEDATA4 .fill x3512 ;
.fill x3513 ;
.fill x3514 ;
.fill x3518 ;
.fill x3519 ;
.fill x351A ;
.fill x351E ;
.fill x351F ;
.fill x3520 ;
.END
实验结论:
一开始看到这个实验觉得用高级语言编写已经挺困难了,现在还要用汇编语言,觉得自己不可能完成。但把思路理清,把该实验拆分后,发现其实只要编写好主要的子程序该实验还是能够完成的。本次实验工程量巨大,耗时也很久,不断地被某些错误折磨,但在整个程序实现完后还是很有成就感。通过这次实验我加深了对LC3汇编语言的理解,学会更好地使用LC3指令,加深对内存的认识,提升我编写代码的能力。并灵活通过添加断点调试的方式发现并解决了许多错误。