汇编程序课程设计总结报告[题目]:迷宫问题[组长]:99090B3 陈晓威(31)[组员]:99090B3 刘兆峰(21) 范 瑜(35) 王学文(20) 唐 英(9) 赵 静(5) 马玲群(38)[问题描述]: 本程序的原型为“钻水管”,即想象一个小球在水管中滚动,小球的位置通过像素坐标反馈,小球是否在迷宫中滚动,则通过颜色判断,即如不是迷宫线的颜色, 则禁止行走。[功能模块]:图形界面及整体规划、链接,由陈晓威和王学文实现限制迷宫范围的外框及迷宫桌面,并制作两幅迷宫图案以供调用,由唐英实现用键盘方向键画迷宫线,要求可以选择线的颜色,并制作为方便用户使用而设计的入出口过渡线,由刘兆峰实现用鼠标画迷宫线,要求通过单击两点连接成线完成,由赵静实现由用户用键盘搜索迷宫路线,要求已走过的路线还可以重新返回再走,由范瑜实现由电脑自动搜索迷宫路径,要求如顺利走出给出成功信息,如陷入死循环或没路可走则给出提示错误的信息,由马玲群实现[具体实现]:模块一:图形界面及整体规划、链接 陈晓威(31) 王学文(20)(一)程序调用关系如下: 主程序MAIN 程序执行 图形界面 Colorset Printinfo Printarrow Mainframe Otherframe Colorselect Rline Cline Blockpos Colorblock Mode1Migong1 Net Drawinmouse Playinkey AutoMigong2 Easydraw Drawinkey RoadnumDelay Testp Threeway Twoway NwayUmov Dmov Rmov Lmov Roadnum 因程序涉及的子程序太多,为链接方便考虑,将所有子程序分为图形界面及程序执行两大部分,通过主程序main调用, 其中程序执行部分的子程序都通过子程序mode1调用,在界面上表现为通过按不同的按钮来调用相应的子程序(二)用户界面如下:************************************************* * Welcome To Labyrinth Games * ************************************************* 按钮 HELP: 用户界面采用键盘与鼠标结合操作方式,共有八个按钮: MAP1(调用地图一)MAP2(调用地图二)USER(用键盘或鼠标画迷宫)EXIT(退出迷宫游戏返回DOS或Windows)PLAY(用户用键盘玩游戏)AUTO(电脑自动玩游戏)CLS(将迷宫主界面清屏为初始状态)MEM(显示游戏制作人员)颜色选择区域提示用户在用键盘画迷宫时可供选择的线条颜色,因游戏使用调色板方式,只有四种颜色可供选择(三)实验心得:在画按钮的边框时,因有很多的边框,起初考虑过调用子程序实现,这样可以节省很大空间,但后来又考虑到每个边框的参数(颜色、坐标)都不相同,如果调用子程序,每次都要改变这些参数,所以最后就改用宏来实现,通过牺牲一些空间使程序读起来更加简洁。本程序将显示方式设为320*200*4 彩色图形方式,在做按钮时遇到一件很麻烦的事,因显示按钮中的字符是按80*25模式计算位置,这样边框和字的坐标不是一个标准,计算出的对应关系又不准确,所以只能通过耐心细致的不断调节,使界面显示达到要求。在将各个模块链接起来的过程中,我自觉要能正确及时地从子程序返回到主程序中是最难搞的,经常不知该把返回语句加到哪里,尤其是在程序执行途中,比如电脑正在自动搜寻路径的过程中。大部分问题通过认真思考现在已经解决,只有一处,就是在调用AUTO子程序后还不知该怎样返回,起初设定为读入ESC键就退出,但仔细检查后发现如果这样实现的话,因为读键使用了中断调用,必须在小球每走一步后就按键一次让系统检测是否为ESC键,否则会因中断而使程序无法继续执行,但这是不可能实现的,后来又想到使用鼠标按键决定是否退出,但因为小球每走一步都有一个延时过程,如果按键的时机不对,也不可能退出,尝试几次之后,这种方法也宣告失败,希望以后有机会能够想到。在程序编制过程中,有很多同学试玩我的游戏,但经常是不知该怎样操作,于是就产生了作一些帮助的想法,因为帮助都定义为字符串变量,所以就定义了一个宏Helpshow来显示帮助内容,以使程序简洁,另外显示帮助的一个关键问题就是掌握显示时机,要做到及时。在界面中有一个MEM按钮,用来显示制作小组成员,因提示栏长度有限,需分两次才能显示完全成员名字,我最初使用延时制造的自动翻页效果来轮番显示两栏内容,用鼠标按键结束这种显示返回到主程序,但与前边提到AUTO中原因一样,效果不太理想,后来改用单击鼠标左键就显示第一栏内容,单击鼠标右键显示第二栏内容,虽然麻烦了一点,但效果还可以。这次课程设计就在两周的忙碌中度过了,首先非常感谢辛勤教导我们的潘老师,是他让我深切感受到编程的乐趣,再次要感谢我们小组的全体成员,是大家的辛勤努力和通力合作才有这个小小游戏的诞生,最后也非常感谢舍友的支持,感谢他们给与我的帮助和指导。这次课程设计可以说收获颇多,因为是第一次接触汇编这种跟机器靠的很近的语言,编程中遇到许多奇事,通过解决它们,的确学到很多有用的知识,看到自己亲手编制的程序能够正确执行,那种乐趣是一般人所体会不到的,今后会继续努力,做一个优秀而快乐的程序员。模块二:限制迷宫范围的外框及迷宫桌面,并制作两幅迷宫图案以供调用 唐 英(9)迷宫:MAP1 迷宫:MAP2 CLS(清屏)(一)实验内容:编写直接可调用的两个迷宫图MAP1,MAP2;CLS是对迷宫的着色,起到清屏作用.其中的迷宫MAP1,MAP2需调用mainframe(其中包含子程序rline﹑cline﹑blockpos﹑colorblock.).CLS中主要函数是blockpos,(二)实验的主要的实现原理调用BIOS中断中的C号功能mov al , rcolormov ah , 0chint 10h画象素点:不间断的写下象素点连成一条直线. rline macro rcolor , lrow , bcol , ecol ;draw horizontal linelocal line1 ;使用local伪操作的局部标号表示的每一局部标号建立唯一的标号来代替在其中存在的每个局部标号. mov dx , lrowmov cx , bcol -------------------------------------------------------- line1 mov ah , rcolor ;象素值如寄存器 al中 mov ah , 0ch int 1ch ; 调用BIOS中断中C号功能写象素 Inc cx ;cx+1即 bcol+1从开始的列值往后移1写下象素点 cmp cx , ecol ;比较结束列值与结束列值 jl rline ;若小于则返回rline1,否则往下执行 endm--------------------------------------------------------mainframe PROC NEARrline 2,60,40,200 ;for migong framerline 2,180,40,200 ;red linecline 2,40,60,180cline 2,200,60,180rline 3,61,41,199 ;for migong frame rline 3,179,41,199 ;yellow line cline 3,41,61,179 cline 3,199,61,179;********************************* blockpos 1,179,199,62,42 CALL colorblock ; for migong background RETmainframe ENDP(三)函数与程序说明:cline函数用来画垂线,主要实现原理与rline完全相同.blockpos函数主要实现清屏功能,按程序要求把迷宫画为绿色,主要实现的原理还是和rline一样,只先画线以后在由线画成块,函现时用CMP,JNE等指令实现子程序line的循环调用.mainframe函数给迷宫画面的镶边,由程序要求把迷宫设定为棕色路线与绿色不能走程序设定底色为兰色,为防止小点满屏乱走所以迷宫镶上红色边和棕色边(如下图示)。 EMBED PBrush 图示程序中主要用到的是宏定义和宏调用,虽然用子程序比较节省存储空间,但是由于宏调用的工作方式和子程序调用的工作方式完全不同。子程序是在程序执行期间由主程序调用的,它只占有它自身大下的一个空间;而宏调用则是在汇编期间展开的,每调用一次就把宏定义体展开一次,因而它占有的存储空间与调用次数有关,因考虑存储空间。但对那些代码较短的且变元较多的功能段,使用宏汇编比较合理,因为调用一个子程序就得重定义一下其中的变量,比较麻烦,也容易出错。(四)课程设计中的注意点及困难:由我负责的三个模块中主要核心原理就是: mov al , bl mov ah , 0ch int 10h写象素点的BIOS中断C号功能调用和宏汇编中的宏定义及宏调用的使用。宏汇编中要注意的就是宏展开后即用实元取代哑元后,所得到的语句应该是有效的,否则汇编程序将会指示出错。在编程中局部变量的定义非常重要,如果定义不当或者不定义都将给调试程序带来困难。(五)课程设计心得体会: 通过本次课程设计,我对汇编语言的认识有了深入的理解,平时不注重实习的我,在本次设计中碰到了许多的困难,比如说我设计的部分中,刚开始对其中各个寄存器所代表的程序所要达到的效果 一点儿都不熟悉,但是经过我的屡次调试,最后通过实验终于认识了我所要编辑的那部分的各参数。在实验中,我们小组尤其发挥了团体精神,我发现我个人所编的只能单独的运行,经过大家数次合编和参数的统一定义,达到了程序的互相调用,最后终于可以链接并且调试成功。模块三:用键盘方向键画迷宫线,要求可以选择线的颜色,并制作为方便用户使用而设计的入出口过渡线 刘兆峰(21) (一)模块功能:在迷宫区域绘制方格坐标底线用键盘绘制迷宫绘制迷宫入口出口提示线,以方便顺利走出迷宫(二)设计思想及源程序:1.绘制方格底线:因为迷宫是按照颜色的不同来辨别通路与障碍的.而且要辨别迷宫的入口和出口,所以在迷宫区域画上方格,以便定位方便.迷宫是在彩色的模式下完成的,用到彩色图形模式,即利用象素来生成彩色图形.程序要求在指定的区域画方格,所以首先把起始位置的坐标送给DX和CX,并用他们来来保留行号和列号,在画每条水平线时,DX(行号)保持不变,CX(列号)从指定的起始位置到制定的中止位置.画下一条线时DX(行号)加1,CX(列号)仍同前.如此循环,知道DX(行号)增加到指定的位置.这样横线绘制完成.竖线的画法和横线画法类似.源程序如下: NET PROC NEAR MOV CX,43 MOV DX,64NET1: MOV AH,0CH MOV AL,3 INT 10H INC CX CMP CX,198 JNE NET1 ADD DX,2 MOV CX,43 CMP DX,178 JNE NET1;************************** MOV CX,43 MOV DX,63NET2: MOV AH,0CH MOV AL,3 INT 10h INC DX CMP DX,178 JNE NET2 ADD CX,2 MOV DX,63 CMP CX,198 JB NET2 RETNET ENDP 2.用键盘绘制迷宫:迷宫的生成方式有两种,这里是用键盘绘制,要求达到一下要求a:按动光标控制键,在屏幕的指定的区域内的上下左右任一方向上绘图.b.每画一点前,由数字键0-3指定该线的彩色值.c.按动ESC键,绘图结束,返回DOS.此程序主要使用了绘象素点的BIOS功能,写象素点所需调用的参数行变量和列变量分别放在DX和CX寄存器中,一开始就先把DX和CX放在迷宫的入口位置,程序从键盘接受一个字符值,首先判断是不是0-3,如果是,则把该象素值保留在BL中,在调用该写点功能时,再传给AL.如果不是字符0-3.则判断是不是ESC,如果是,则退出该循环.如果也不是,则判断是不是上下左右,当按动上时,DX的值减1,当按动下时,DX的值加1,同理,左时CX减1,右时CX加1,这样由CX和DX的值决定了写点的坐标位置.源程序如下: DRAWINKEY PROC NEAR MOV CX,42 MOV DX,70 GETC: MOV AH,0 INT 16h CMP AH,ESCAPE JZ EXIT0 CMP AL,33H JG PLOT CMP AL,30H JL PLOT MOV BL,AL AND BL,03 JMP GETC PLOT:MOV AL,AH CMP AL,UP JNZ NOT_UP DEC DX NOT_UP:CMP AL,DOWN JNZ NOT_DOWN INC DX NOT_DOWN:CMP AL,RIGHT JNZ NOT_RIGHT INC CX NOT_RIGHT:CMP AL,LEFT JNZ WRITE DEC CX;************************************** WRITE: MOV AL,BL MOV AH,0CH INT 10H JMP GETC EXIT0: RETDRAWINKEY ENDP3.绘制迷宫出口入口提示线.因为该迷宫图是以一个象素为基本单位的,所以出口的点非常的小,为了方便玩家顺利的走出迷宫,特绘制入口出口提示线.源程序如下: easydraw proc near mov cx,186 mov dx,70nex1: mov ah,0ch mov al,0 int 10h inc cx cmp cx,199 jne nex1 mov cx,42 mov dx,70nex2: mov ah,0ch mov al,0 int 10h inc cx cmp cx,55 jne nex2 reteasydraw endp注:(42,70)和(199,70)分别为入口和出口的坐标.(三)编程体会:通过这次课程设计我对汇编语言有了进一步的了解.知道编制图形程序是程序设计中非常有趣和有价值的工作之一,在图形绘制方面,汇编语言具有潜在的优点,因为显示屏幕上的每一个图象都是由成千上万的元素组成,处理这些象素需要大量的指令,就速度而言,汇编语言比高级语言要快的多.程序采用的是调色板来配置颜色的,虽然颜色的选择很方便,但是美中不足的是它供选择的颜色过于单调.模块四:用鼠标画迷宫线,要求通过单击两点连接成线完成赵 静(5) 紧张而有趣的课程设计结束了,虽然只有短短的两周时间,可我却获益匪浅,而从中体会到的乐趣更是难以用言语表达。 这次我们组做的题目是‘迷宫’,我负责的那部分是MOUSE功能调用以及相关的一些鼠标操作。初看题目,真有点摸不找头脑的感觉,可经过我们小组成员的共同讨论,各抒己见,还有组长陈晓威的深入分析,我们每一个人都大体清楚了个人的模块和总体的框架,找到了入手点。我所做的这部分模块是MOUSE功能调用和相关的一些鼠标操作,其实主要是用鼠标实现绘制迷宫的功能。这其中用到了许多MOUSE功能调用中的INT 33H,主要有:mouseinit PROC NEAR MOV AX,0 ;初始化鼠标 INT 33h RET mouseinit ENDP;--------------------------------------------------mouseshow PROC NEAR MOV AX,1 ;显示鼠标光标 INT 33h RETmouseshow ENDP;--------------------------------------------------mouseshut PROC NEAR MOV AX,2 ;关闭鼠标光标 INT 33h RETmouseshut ENDP;-------------------------------------------------mousestau PROC NEAR MOV AX,3 ;取鼠标位置,CX X坐标(水平), DX Y坐标(垂直) INT 33h RET mousestau ENDP;---------------------------------------------------mousepressed PROC NEAR MOV BX,0 MOV AX,5 ;取鼠标按下信息 INT 33h RETmousepressed ENDP;--------------------------------------------------mouseliberty PROC NEAR MOV BX,0 MOV AX,6 ;取按钮按下信息 INT 33h RETmouseliberty ENDP实验心得:在调用INT 33H 的07、08号功能限定迷宫的范围时,因为迷宫横坐标为40—200,纵坐标为60—180,所以开始我在调用07号功能时,CX中存放40,DX中存放200,调用08号功能时,CX中存放60,DX中存放180,如下:limit1 PROC NEAR MOV AX,07h MOV CX,40 MOV DX,200 INT 33h MOV AX,08h MOV CX,60 MOV DX,180 INT 33h RETlimit1 ENDP后来调试时发现这样定义的坐标不对,经过阅读有关参考资料,才知道因我使用的是04号显示模式,在这种模式下,X=2*屏幕XY=屏幕Y,所以后改为横坐标范围为80—400,纵坐标范围为60—180,如下:limit1 PROC NEAR MOV AX,07h MOV CX,80 MOV DX,400 INT 33h MOV AX,08h MOV CX,60 MOV DX,180 INT 33h RETlimit1 ENDP调试通过,通过这次经验,我明白了很多东西是要通过实践才能发现的,尤其是编程,经常有很多意想不到的错误,今后要加强实践环节的训练。模块五:由用户用键盘搜索迷宫路线,要求已走过的路线还可以重新返回再走 范 瑜(35)模块功能:按动键盘玩迷宫游戏,当你走出迷宫时显示“You are successful”。按键盘方向键顺着已画好的迷宫线(蓝色)走,留下红色的路线,如果发现走错往回走,则把走过的路线(红色)擦去(改回蓝色),不是迷宫线的地方不能走。需要注意的问题:判断键盘的动作,有关象素值的有关问题,读象素,写象素,判断语句,跳转语句。设计思想:用键盘玩首先要检测键盘的动作,先查找扫描码值,根据扫描码的比较,对象素的坐标值进行处理,DX,CX值或加或减。读, 写象素, 需要了解读写象素的BIOS中断的使用方法。比较象素值蓝色改为红色,红色改为蓝色。如果不在迷宫管道上走,还要返回象素行列值,以保证坐标值在迷宫管道上。程序流程图如下:具体程序如下:;键盘箭头,ESC的扫描码up EQU 48hdown EQU 50hright EQU 4dhleft EQU 4bhescape EQU 01h ;01h is scan code in AH , 1bh is digit code in ALplayinkey proc near ;置入口所在行列处为红色 mov dx,70 mov cx,42 mov bx,2 ;红色 mov ah,0ch mov al,bl int 10h mov di,0 ;置标志位di=0;行列值与出口行列值比较line00: cmp dx,70;与行比较 jnz get_char1 cmp cx,198;与列比较 jz exit7;如果行列相等则结束;从键盘读动作get_char1: mov ah,0 int 16h;是up则置标志位为0,不是则跳转up1: mov al,ah cmp al,up jnz not_up1 mov di,0 dec dx jmp read;是down则置标志位为1,不是则跳转not_up1: cmp al,down jnz not_down1 mov di,1;是下则置标志位=1 inc dx jmp readnot_down1:cmp al,right jnz not_right1 mov di,2;是右则置标志位=2 inc cx jmp readnot_right1:cmp al,left jnz ifesc;不是则跳转到是按下ESC的情况 mov di,3;是左则置标志位=3 dec cx ;读dx行cx列的象素值 read: mov ah,0dh int 10h;读象素值;不是蓝色则跳转,是则改为红色 cmp al,0;是蓝色吗?jnz not_blue1;不是则跳转 mov ax,2 mov ah,0ch int 10h;改为红色 jmp line00;不是红色则跳转,是则改为蓝色not_blue1:cmp al,2;是红色吗? jnz not_red1;不是则跳转 mov ax,0 mov ah,0ch int 10h;改为蓝色 jmp line00;既不是蓝色也不是红色,必走出迷宫管道根据标志位返回dx,cx值not_red1: cmp di,0;输入up则dx减1,恢复输入前状态 jnz not_zero1 inc dx jmp line00not_zero1:cmp di,1 jnz not_one1 dec dx jmp line00not_one1: cmp di,2 jnz not_two1 dec cx jmp line00not_two1: inc cx jmp line00;如果中途按下ESC键则退出游戏的情况ifesc: cmp al,escape jnz line00 ;退出游戏并在屏幕help栏显示”you are successful”exit7: helpshow G call mode1 retplayinkey endp遇到的问题:我在完成这个程序的编写前,先是置dx,cx,读键盘动作,置dx,cx值,读这个坐标处的象素值,判断。这样做遇到了问题。 心得:在这次课程设计中练习灵活应用跳转表,熟悉了键盘的输入情况;体会到如何读,写象素以及其中要注意到的问题模块六:由电脑自动搜索迷宫路径,要求如顺利走出给出成功信息,如陷入死循环或没路可走则给出提示错误的信息马玲群(38)模块思想:用回溯算法;建树算法于八皇后问题雷同,此处n<=3;用坐标指定入口、出口;遇岔路口时把当前坐标入栈,后逐一试验如不通则返回原位置试另外一条;路障的区分由颜色来判断,即底色和迷宫路径颜色不同,一直到坐标为出口坐标结束程序;模块存在问题:路径还不为最短路径,没有解决;当迷宫不同时,没有显示出错信息;实验感受:自己知识覆盖面比较窄;有些东西(如数据结构中最短路径部分)还不是很精;与同学有一定的合作;99090B3迷宫小组全体成员感谢老师的教导!感谢这次编程实践带给我们的乐趣!我们会继续努力,我们要做快乐的程序员!99090B3迷宫小组全体成员2002-1-24汇编程序课程设计总结报告----迷宫问题PAGE PAGE 19——————————————————————————————99090B3 第四组 2002-1-24RlineClineBlockposColorblockSetcursorShowmessFrameposOneframeFrameposOneframeBlockposColorblock迷宫主界面颜色选择区管道外的颜色,则根据标志位置dx,cx的值(让行列值复位)di置0结 束开 始改为蓝色改为红色出口行列值?红色吗?置入口所在行列处为红色蓝色吗?读象素从键盘输入动作根据键盘输入的扫描码置标志位di的值,dx,cx的值置标志位di =0绿 色红 色棕 色
温馨提示
请用电脑打开本网页,即可以免费获取你想要的了。