手机版 | 登陆 | 注册 | 留言 | 设首页 | 加收藏
当前位置: 网站首页 > 音响设备技术 > 文章 当前位置: 音响设备技术 > 文章

俺也汇编一下:EMU8086

时间:2009-08-13    点击: 次    来源:本站原创    作者:佚名 - 小 + 大

对不住各位看官了……这个EMU8086模拟器是Windows下的,还是破解的……我只是为了完成计组老师的作业而已。只是有道题比较有意思,我深深地想了好久,发现一些问题,估计老师不会认真改我的作业,我把它发上来发泄发泄,嗯。

话说EMU8086预先弄了几个PORT,其中PORT9就是实现了一个机器人的东东。具体描述如下:在一个9X6的地图内,有墙、灯、机器人三种东西。机器人碰到墙和灯都过不去,但是碰到灯的时候会自动改变灯的状态,也就是关灯或者开灯。
现在在地图上画一个地图,机器人使用给定的算法会产生死角,问怎么样消除死角。

话说原来给定的代码太弱了,一眼看出破绽:机器人碰墙只能单纯地朝一个方向转,那么碰到开了一口的闭合空间时,一旦进去就出不来了(如图),必然得改进。改进的方法有两个,一个是把行走改成随机方向,那么机器人再怎么囧最后也能走出去,可是老师不提倡随机,那么只好接着改了。

在不使用随机走法的情况下,使用回溯法是更好的解决方案。回溯法用在走迷宫的时候比较实用,遵循“右手法则”地回溯搜索路径,最后走出死角。

然而一般“右手法则”下的回溯会产生另一个问题,就是在空白面积比较大的时候,会出现“绕某点打转”的现象,如下图:

这在机器人行走中是致命的。

我原计划采用的是“撒米标记法”解决此问题。但是由于对数组的使用不熟悉,没有解决这个问题。(关键在这,- -b)在这里仅写出思路:“撒米标记法”。使用一个数组来记录当前点是否已经被车子移到过,如果当前点在之前已经在同个方向上被访问过,则机器人不再继续前进,而是直接选择一个其他方向,继续按照右手法则行走。

第二个死角的产生比较麻烦,是软件本身产生的“副作用”。此“副作用”在如下情况下执行关灯/开灯操作时出现:
当程序员手动执行机器人转向操作时,软件会记录这一次转向。一次左转和一次右转会抵消。不连续的两次转向不相关。所以转向结束后,会有一个“净转向”值。此时机器人如果正好面对一盏灯,在执行关灯/开灯操作之后,机器人会自动逆着“净转向”的方向转动相应次数。例如下图:

机器人在两次右转之后,面对的是灯。在关完灯的同时,机器人会自动向左转两次,恢复到原来状态。
了解了转向的副作用,便可知下图会产生一个死角:

为了解决这个死角,可以采用“抵消副作用”法。对于以上右手法则,可以很容易获得其状态机:(其实这个状态机挺扯的,原谅我自动机课没学好T_T)

圈内数字表示当前状态下的净转向值。
具体解法可看附件的代码。

#MAKE_BIN##CS = 500##DS = 500##SS = 500#    ; stack is set#SP = FFFF#   ; automatically.#IP = 0#R_PORT 		EQU 9;BL	255: turned left;	0: turned none;	1: turned right;BH	0: initial state;	1: try right;	2: try ahead;	3: try left;	4: try back;	when it moves ahead, BH should be 0eternal_loop:	CALL	WAIT_ROBOT	MOV	AL, 4	OUT	R_PORT, AL	CMP	BH, 0		; judge if initial state	JE	first_step	; first_step	CALL	WAIT_EXAM	; else judge how to move	IN	AL, R_PORT + 1	CMP	AL, 0		; nothing?	JE	forward		; so, forward	CMP	AL, 255 	; wall?	JE	meet_wall	; so, turn right	CMP	AL, 7		; switched-on lamp?	JE	switch_off	; so, switch it off and do something	CMP	AL, 8		; switched-off lamp?	JE	switch_on	; so, switch it on and do somethingfirst_step:	ADD	BH, 1	MOV	BL, 1	JMP	turn_rightmeet_wall:	ADD	BH, 1	SUB	BL, 1	JMP	turn_leftmeet_lamp:	ADD	BH, 1	CMP	BL, 255	JE	turn_around	SUB	BL, 1	CMP	BL, 0	JE	eternal_loop	JMP	turn_leftturn_left:	CALL	WAIT_ROBOT	; turn left operation	MOV	AL, 2	OUT	R_PORT, AL	JMP	eternal_loop	; go againforward:	MOV	BH, 0		; when forward, back to initial state	MOV	BL, 0		; no turn mark	CALL	WAIT_ROBOT	; go ahead	MOV	AL, 1	OUT	R_PORT, AL	JMP	eternal_loop	; go again!switch_off:	CALL	WAIT_ROBOT	; turn off the lamp	MOV	AL, 6	OUT	R_PORT, AL	JMP	meet_lampswitch_on:	CALL	WAIT_ROBOT	; turn on the lamp	MOV	AL, 5	OUT	R_PORT, AL	JMP	meet_lampturn_right:	CALL	WAIT_ROBOT	; turn right operation	MOV	AL, 3	OUT	R_PORT, AL	JMP	eternal_loop	; go againturn_around:	CALL	WAIT_ROBOT	; turn right twice to turn around	MOV	AL, 3	OUT	R_PORT, AL	CALL	WAIT_ROBOT	MOV	AL, 3	OUT	R_PORT, AL	JMP	eternal_loop	; go againWAIT_ROBOT	PROCbusy:	IN	AL, R_PORT+2	TEST	AL, 00000010b	JNZ	busy ; busy, so wait.	RETWAIT_ROBOT	ENDPWAIT_EXAM	PROCbusy2:	IN	AL, R_PORT+2	TEST	AL, 00000001b	JZ	busy2 ; no new data, so wait.	RETWAIT_EXAM	ENDP

写完了。反正问题就在,会绕圈……

等考完事再来看。估计也就是几个register的问题。

最后附上一个可启动的小东东:打字训练——所谓的“操作系统”作业,Orz。专门为某打字不按指法的家伙准备的。

谢帆说还要把Loader和Kernel分开写,我继续Orz了,这个小东西填MBR的牙缝都不够呢,还分开……

上一篇:汇编语言程序设计操作性实验Debug、Emu8086、MASM的使用

下一篇:汇编工具 之 EMU8086

备案ICP编号  |   QQ:285250603  |  地址:湛江市  |  电话:15322199012  |  
Copyright © 2026 天人文章管理系统 版权所有,授权www.yajiupc.top使用 Powered by 55TR.COM