📄 maze.asm
字号:
;过迷宫的算法。
LIST EQU 30H ;有效路线记录表的首址。
CONT DATA 30H ;有效路线中的岔路口计数器。
OK BIT 00H ;成功标志。
RETURN BIT 01H ;返回标志。
ERROR BIT 02H ;出错标志。
ORG 0000H
LJMP TEST
ORG 100H
TEST: MOV DPTR,#LINE1;模拟岔路口数据表格首址。
LCALL SEARCH ;通过未知迷宫的搜索算法。
NOP ;算法输出的有效路线记录:
NOP ;16H(记录长度为22字节)
NOP ;3EH,26H,3FH,26H,29H,2DH,25H
NOP ;2DH,2DH,3EH,2DH,25H,2DH,26H,2AH
NOP ;29H,2EH,2EH,2DH,2AH,25H,80H
NOP ;
MOV DPTR,#LINE2;模拟岔路口数据表格首址。
LCALL GO ;通过已知迷宫的算法。
STOP: LJMP STOP
SEARCH: CLR OK ;初始化成功标志为零(尚未成功)。
CLR RETURN ;初始化返回标志为零(向前搜索)。
MOV CONT,#0 ;初始化有效路线记录为空表。
MOV R0,#LIST;初始化线性表指针。
S0: LCALL ON ;接通电机电源,使机器鼠向前运动。
S1: LCALL DETECT ;检测当前位置的情况。
CJNE A,#10H,S2;是在直巷子里吗?
SJMP S1 ;是,不关电机,一边前进一边检测。
S2: LCALL OFF ;有情况,断开电机电源使机器鼠停下来。
CJNE A,#80H,S3;是出口吗?
INC R0 ;调整指针。
INC CONT ;记录长度加一。
MOV @R0,A ;保存出口信息。
SETB OK ;是出口,设置成功标志。
RET ;有效路线搜索结束。
S3: JNZ S4 ;是死胡同尽头吗?
LCALL BACK ;是,向后转。
SETB RETURN ;设置返回标志。
SJMP S0 ;从死胡同返回。
S4: CJNE A,#14H,S5;是路段内部的左转弯吗?
LCALL LEFT ;是,向左转。
SJMP S0 ;继续前进。
S5: CJNE A,#18H,S6;是路段内部的右转弯吗?
LCALL RIGHT ;是,向右转。
SJMP S0 ;继续前进。
S6: MOV B,A ;保存检测信息。
JB RETURN,S7;是返回状态吗?
INC R0 ;不是,调整到下一个地址,准备保存新岔路口记录。
MOV @R0,B ;保存新岔路口记录。
INC @R0 ;在新岔路口,按左手“顺墙摸”选择第一岔路。
INC CONT ;记录表格长度加一。
SJMP S9 ;进入新的路段。
S7: MOV A,@R0 ;是返回状态,取原记录。
ANL A,#33H ;分离出岔路总数和当前岔路的编号。
MOV R2,A ;暂存。
SWAP A ;交换位置。
XRL A,R2 ;进行比较。
JZ S8 ;相同否?
INC @R0 ;不相同,还有未经搜索的岔路,选择下一条岔路。
CLR RETURN ;清除返回标志,准备进行新的搜索。
SJMP S9 ;进入新的路段。
S8: DEC CONT ;相同,所有岔路均已搜索过,删除该岔路口。
DEC R0 ;记录指针后退。
S9: JNB B.2,S0 ;若左边没有岔路,继续向前走。
LCALL LEFT ;若左边有岔路,则向左转(左手“顺墙摸”法则)。
LJMP S0 ;继续前进。
GO: MOV R7,CONT ;取有效路线记录元素总数。
MOV R0,#LIST+1;指向第一个记录元素。
CLR ERROR ;初始化出错标志。
GO0: LCALL ON ;接通电机电源,使机器鼠向前运动。
GO1: LCALL DETECT ;检测当前位置的情况。
CJNE A,#10H,GO2;是在直巷子里吗?
SJMP GO1 ;是,不关电机,一边前进一边检测。
GO2: LCALL OFF ;有情况,断开电机电源使机器鼠停下来。
CJNE A,#80H,GO3;是出口吗?
RET ;顺利通过迷宫。
GO3: CJNE A,#14H,GO4;是路段内部的左转弯吗?
LCALL LEFT ;是,向左转。
SJMP GO0 ;继续前进。
GO4: CJNE A,#18H,GO5;是路段内部的右转弯吗?
LCALL RIGHT ;是,向右转。
SJMP GO0 ;继续前进。
GO5: XRL A,@R0 ;碰到岔路口,和记录信息比较。
ANL A,#0FCH ;分离出岔路口类型比较结果。
JNZ GOE ;岔路口类型与记录中的类型不同,出错。
MOV A,@R0 ;读取记录元素。
MOV B,A ;暂存。
ANL A,#3 ;分离出岔路编号。
CJNE A,#3,GO7;是选择第三岔路吗?
LCALL RIGHT ;向右转弯。
SJMP GO9 ;继续向前走。
GO7: CJNE A,#2,GO8;是选择第二岔路吗?
JNB B.3,GO9 ;若右边没有岔路,继续向前走。
LCALL RIGHT ;若右边有岔路,向右转弯。
SJMP GO9 ;继续向前走。
GO8: JNB B.2,GO9 ;选择第一岔路,若左边没有岔路,继续向前走。
LCALL LEFT ;若左边有岔路,则向左转。
GO9: INC R0 ;调整记录指针。
DJNZ R7,GO0 ;记录元素尚未读完,继续前进。
GOE: CLR OK ;记录全部读完或迷宫发生变化,清除成功标志。
SETB ERROR ;设立出错标志。
RET ;失败返回。
ON: NOP ;电机启动子程序(省略)。
NOP
RET
OFF: NOP ;电机关闭子程序(省略)。
NOP
RET
LEFT: NOP ;向左转弯子程序(省略)。
NOP
RET
RIGHT: NOP ;向右转弯子程序(省略)。
NOP
RET
BACK: NOP ;向后转弯子程序(省略)。
NOP
RET
DETECT: CLR A ;检测子程序(用读表格来模拟)。
MOVC A,@A+DPTR
INC DPTR
RET
LINE1: DB 3CH,18H,18H,00H,14H,14H,3CH,14H,18H ;图11-1所示迷宫在左手“顺
DB 24H,14H,00H,18H,2CH,14H,14H,18H,3CH ;墙摸”时沿路检测得到的编码。
DB 2CH,18H,00H,14H,28H,14H,24H,00H,2CH
DB 14H,00H,18H,28H,18H,24H,3CH,18H,18H
DB 00H,14H,14H,3CH,14H,18H,18H,14H,24H
DB 2CH,18H,18H,14H,14H,00H,18H,18H,14H
DB 14H,28H,00H,24H,2CH,18H,28H,18H,18H
DB 2CH,24H,18H,2CH,18H,2CH,3CH,00H,3CH
DB 2CH,18H,18H,24H,2CH,24H,00H,2CH,14H
DB 28H,00H,24H,28H,14H,14H,14H,18H,2CH
DB 14H,18H,18H,00H,14H,14H,18H,28H,2CH
DB 00H,28H,14H,18H,2CH,14H,18H,28H,18H
DB 00H,14H,24H,18H,24H,80H
LINE2: DB 3CH,14H,18H,24H,14H,14H,18H,3CH ;图11-1所示迷宫在有效
DB 14H,18H,18H,14H,24H,18H,28H,18H ;路线记录的指引下,
DB 18H,2CH,24H,18H,2CH,18H,2CH,3CH ;沿路检测得到的编码。
DB 2CH,18H,18H,24H,2CH,24H,14H,28H
DB 28H,14H,14H,14H,18H,2CH,2CH,14H
DB 18H,2CH,14H,18H,28H,18H,24H,80H
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -