微机原理研讨报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
微机接口研究性教学专题三
题目名称(题目2 ) 简单动画设计
学院电信学院
班级
组员
教师
一概述
1.课程设计的目的
对学生掌握知识的深度、运用理论去处理问题的能力、实验能力、课程设计能力、书面及口头表达能力进行考核。
汇编语言程序设计课程设计是在教学实践基础上进行的一次大型实验,也是对该课程所学理论知识的深化和提高。
因此,要求学生能综合应用所学知识,设计与制造出具有较复杂功能的应用系统,并且在实验的基本技能方面上进行一次全面的训练。
培养学生综合运用所学知识独立完成汇编程序课题的能力。
使学生能够较全面地巩固和应用课堂中所学的基本理论和程序设计方法,能够较熟练地完成汇编语言程序的设计和调试。
提高学生对工作认真负责、一丝不苟,对同学团结友爱,协作攻关的基本素质。
培养学生从资料文献、科学实验中获得知识的能力,提高学生从别人经验中找到解决问题的新途径的悟性,初步培养工程意识和创新能力。
培养学生勇于探索、严谨推理、实事求是、有错必改,用实践来检验理论,全方位考虑问题等科学技术人员应具有的素质。
2.课程设计的要求
利用BIOS系统功能调用,进行简单的动画设计,并根据以下提示信息进行选择:
1――小鸟从屏幕飞过;
2――汽车按水平方向从屏幕上“开”过去;
3――退出
提高要求:
加入音乐播放。
二方案设计
1. 主程序设计思想:
此动画程序要求结构化的显示两个动画效果:小鸟飞过和小车开过。
程序要求能多次执行以上两种动画并有退出选项。
则我们可以设计三个选项以供用户选择:1-小鸟、2-小车和q-退出程序。
三个选项分别可以用三个过程实现其功能。
动画的原理实质上是在屏幕上连续的间隔较小的地方显示相同的图案。
由于人眼具有视觉暂留的特性,我们就会看到“运动”的画面。
2. 小鸟及汽车图案和加入音乐设计思想:
首先讨论小鸟图像形成及移动部分的方案。
我们通过查阅资料,决定以一组字符组合来形成小鸟图像(即文本方式),用字符形成小鸟图像,主要是利用BIOS 中的INT 10H 中断,即显示器中断,INT 10H 中的09H 号功能是在光标制定位置处写字符和属性。
程序结构图大致如下:
MOV AH,09H ;置光标
MOV AL,‘字符’ ;字符ASCII 码
MOV BL,7 ;字符属性
MOV BH,0 ;第0页
MOV CX,数量值 ;字符重复个数
INT 10H
汽车图形由7个文本字符组成,从左到右,车体是由字母R (ASCII 码为52H ),1/2阴影符(ASCII 码为B1H ),和两个实心方块(ASCII 码为DBH )组成,两个车轮是字母O (ASCII 码为4FH ),和笑脸符号(ASCII 码为02H ),以上七个文本字符都是以正常属性显示。
汽车各字符的相对位移量如图2.2:
开始显示车体,R 是显示的第一个字符,其相对位移量定为(0,0),第二个阴影符号在R 的右边一列,所以相对R 的位移量为(0,1),两个实心方块都是在前一个字符的同一行的右边一列,所以位移量都为(0,1)。
前轮比最后一个方块符号的行数加1,但仍在同一列上,所以它的位移量为(1,0),后轮相对前轮行数不变,但列数减了3,所以位移量应是(0,-3)。
最后显示出笑脸,是相对于后轮位移量是(-2,1)。
如汽车图形可定义变量定义如下:
CAR DB 7
(0(-2, 1) 图2.2 汽车字符表
DB 52H,7,0,0 ;字符R的ASCII码,及字符属性值为7,相对位移量为0,0
DB 0B1H,7,0,1 ;阴影符的ASCII码,及字符属性值为7,相对位移量为0,1
DB 0DBH,7,0,1 ;实心方块的ASCII码,及字符属性值为7,相对位移量为0,1
DB 0DBH,7,0,1 ;实心方块的ASCII码,及字符属性值为7,相对位移量为0,1
DB 4FH,7,1,0 ;大写字母O的ASCII码,及字符属性值为7,相对位移量为1,0
DB 4FH,7,0,-3 ;大写字母O的ASCII码,及字符属性值为7,相对位移量为0,-3
DB 02H,7,-2,1
加入音乐程序也是一个比较重要的环节,我们尝试了好听的音乐,未成功,所以这里采用了产生指定频率声音,中间涉及到扬声器发声部分。
我们采用了定时器控制。
产生指定频率声音的程序段如下:
PUSH AX ;保存ax的值
MOV AL,0B6H ;给2号定时器的43端口送入一个特定的数0B6H
OUT 43H,AL
MOV AX,34DCH
DIV BX
OUT 42H,AL ;给42H端口装入一个16位的计时常数(533H*896/频率)MOV AL,AH
OUT 42H,AL
IN AL,61H ;获取61h端口的当前值
OR AL,03H ;把61h端口低二位置1,即打开蜂鸣器
OUT 61H,AL ;输出数据到61h端口
POP AX ;恢复ax的值
主程序:
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK
START: MOV AX,DATA
MOV DS,AX
MOV AH,0
MOV AL,4 ;设置显示方式为320*200彩色图形方式
INT 10H
LEA DX,STRING
MOV AH,9 ;在显示器上显示字符串提示信息
INT 21H
MOV AH,1
INT 21H ;从键盘读取字符到AL寄存器
CMP AL,‘1’;比较AL是否等于1
JNE A ; 不相等则转移到A
CALL xiao ;相等则调用xiao子程序
A: CMP AL,32H ;比较AL是否等于2
JNE B ; 不相等则转移到B
CALL qiche ; 相等则调用qiche子程序
B: CMP AL,’q’;比较AL是否等于q
JNE START ; 不相等则转移到START,重新输入字符
MOV AH,4CH ; 相等则终止当前程序。
INT 21H
主程序主要实现与用户的交互,首先程序会提示用户想要进行什么操作。
是显示小鸟动画、汽车动画还是退出。
这里对应的给用户提供的选项是“1”、“2”和“q”。
当用户输入他们的选项之后,主程序要判断用户的输入调用相应的功能模块来满足用户的要求。
我们假设用户输入字符为X,那么首先我们将X与“1”比较。
如果相同则程序调用小鸟动画模块为用户显示动画。
若不为“1”则要继续与“2”想比较。
相等则调用汽车动画,不等则继续与“q”想比较。
相等则正常退出,不等则说明用户输入非法字符主程序返回到选择界面用户可以继续选择。
特别说明:汇编语言的选择结构不同于C语言的选择结构,程序设计过程中要特别小心。
避免将造成潜在的BUG.
2) 清屏宏定义
CLEAR MACRO pch,pcl,pdh,pdl,pbh ;清屏宏定义
MOV AH,0
MOV AL,4
INT 10H
MOV AH,6 ;调用6号功能
MOV AL,0 ;设置整个屏幕为空白
MOV CH,pch
MOV CL,pcl ;窗口左上角(0行,0列)
MOV DH,pdh
MOV DL,pdl ;窗口右下角(24行,79列)
MOV BH,pbh ;正常属性显示
INT 10H
ENDM
宏定义分为带参宏定义与无参宏定义。
宏定义的功能旨在减少代码量和提高程序的结构化程度。
一个定义好的宏可以在程序中被多次调用,从而增加了程序员和程序本身的效率。
其中,无参宏定义的格式为:
宏名MACRO
宏体
ENDM
带参宏定义的格式为:
宏名MACRO 形参1,形参2
宏体
ENDM
它们的调用格式为:
宏名[实参]
清屏宏为一个带有五个参数的带参宏。
它的功能是将屏幕中一定区域的内容清楚,为接下的显示提供屏幕空间。
要想进行显示操作就要了解BIOS(INT 10H)调用。
清屏宏中用到了六号功能调用:
6号功能:初始窗口或向上滚动
入口参数:AH=6,AL=上滚行数(AL=0时,整个屏幕为空白)
CX=上滚窗口左上角的行、列号
DX=上滚窗口右下角的行、列号
BH=空白行的属性
出口参数:无
在清屏宏的五个参数中,pch和pcl的值分别赋给CH和CL寄存器,这样所要清屏区域的左上角的坐标就设置好了。
同样,将pdh和pdl的值赋给DH和DL 寄存器,设置好右下角的坐标。
BH寄存器取得pbh的值设置空白行的属性。
最后INT 10h,调用BIOS显示设置实现清屏功能。
三流程设计和程序编写
1. 主程序流程图如图3.1:
图3.1 主程序流程图
2. 源程序代码
源代码:
DATA SEGMENT
INFO1 DB 0DH,0AH,'INPUT 1,2,OR q:(1:bird,2:car,q:exit) $'
BUFA DB 200
DB?
DB 200 DUP(0)
BUFB DB 200 DUP(?)
CAR DB 7 ;小汽车的字符图形表
DB 52H,7,0,0
DB 0B1H,7,0,1
DB 0DBH,7,0,1
DB 0DBH,7,0,1
DB 4FH,7,1,0
DB 4FH,7,0,-3
DB 2,7,-2,1
CHAR_CNT DW?
POINTER DW?
LINE_ON DB?
COL_ON DB?
ZONGZUOBIAO DB 13,13,11,10,10,9,20,6,9,5,3,2,1,9,19,9,
10,11,11,11,12,13,14;小鸟的字符图形表
HENGZUOBIAO DB 1,2,3,4,5,6,6,7,7,8,9,10,11,12,12,13,14,15,16,17,18,19,20 SHULIANG DB 2,4,6,7,7,8,3,1,14,18,20,20,23,7,4,6,5,4,4,4,3,2,1
FLAG DW 0
YIDONG DB 0
YANSHI DW 0
DATA ENDS
STACK SEGMENT stack
DB 200 DUP(0)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
start:mov ax,data
mov ds,ax
mov ah,0 ;设置显示方式为320*200彩色图形方式
mov al,3
int 10h
lea dx,info1 ;在显示器上显示字符串提示信息
mov ah,9
int 21h
mov ah,0 ;从键盘读取字符到AL寄存器
int 16h
CMP AL,31H ;比较AL是否等于1
JNE A
CALL XIAO
A: CMP AL,32H ;比较AL是否等于2
JNE B
CALL QICHE
B: CMP AL,71H ;比较AL是否等于q
JNE START
MOV AH,4CH ;终止当前程序并返回调用程序
INT 21H
CLEAR MACRO pch,pcl,pdh,pdl,pbh ;清屏宏定义
MOV AH,0
MOV AL,4
INT 10H
MOV AH,6 ;调用6号功能
MOV AL,0 ;设置整个屏幕为空白
MOV CH,pch
MOV CL,pcl ;窗口左上角(0行,0列)
MOV DH,pdh
MOV DL,pdl ;窗口右下角(24行,79列)
MOV BH,pbh ;正常属性显示
INT 10H
ENDM
xiao proc ;小鸟子程序
PUSH DS
MOV AX,0
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV FLAG,0
MOV YIDONG,70
;描绘小鸟图像
LOOP4:
MOV AH,02H ;设置光标位置
LEA BX,HENGZUOBIAO
MOV CX,FLAG
ADD BX,CX
MOV DH,[BX] ;DH代表行号
LEA BX,ZONGZUOBIAO
ADD BX,CX
MOV DL,[BX] ;DL代表列号
ADD DL,YIDONG
MOV BH,0 ;表示页号
INT 10H
MOV AH,09H ;在当前光标位置处写字符和属性
MOV AL,76H ;设置字符ASCII码
LEA BX,SHULIANG
MOV DX,FLAG
ADD BX,DX
MOV CL,[BX] ;CX代表写入字符数
MOV CH,0
MOV BH,0
MOV BL,16H ;字符属性
INT 10H
INC FLAG
CMP FLAG,22 ;表示要写23次
JNA LOOP4
;JMP LOOP3
Fasheng: ;发声程序
MOV AL,0B6H
OUT 43H,AL
MOV AX,34DCH
MOV DX,12H
DIV BX
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
IN AL,61H
OR AL,03H
OUT 61H,AL
LOOP3:
MOV FLAG,0
;小鸟飞行程序
LOOP2:
MOV AH,02H ;置光标位置
LEA BX,HENGZUOBIAO
MOV CX,FLAG
ADD BX,CX
MOV DH,[BX]
LEA BX,ZONGZUOBIAO
ADD BX,CX
MOV DL,[BX]
ADD DL,YIDONG ;纵坐标(相当于列)加上40
MOV BH,0 ;选择在第0页
INT 10H
MOV AH,09H ;在当前光标位置处写字符和属性MOV AL,76H ;字符的ASCII码值
LEA BX,SHULIANG
MOV DX,FLAG
ADD BX,DX
MOV CL,[BX] ;cx为写入的字符数
MOV CH,0
MOV BH,0 ;写入的页数
MOV BL,16H ;字符属性
INT 10H
INC FLAG
CMP FLAG,22
JNA LOOP2
;JIXU:
mov YANSHI,5
CALL DLY
MOV AH,02H
MOV DX,0
MOV BH,0
INT 10H
MOV AH,09H ;清除前一帧图像
MOV AL,' '
MOV CX,1700
MOV BL,07H
INT 10H
DEC YIDONG
CMP YIDONG,0 ;飞行到纵坐标为0处时将重新从开始出飞行JA LOOP3
MOV YIDONG,70
JMP LOOP3
TUICHU:
RET
xiao endp
DLY PROC NEAR ;延时子程序
PUSH CX
PUSH DX
MOV DX,1000
DL1: MOV CX,680
DL2: LOOP DL2
DEC DX
JNZ DL1
POP DX
POP CX
RET
DLY ENDP
QICHE PROC near ;汽车子程序
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0
MOV AL,4
INT 10H
MOV AH,0BH ;设置彩色组颜色为绿、红、黄
MOV BH,01
MOV BL,00
INT 10H
CLEAR 33,33,24,79,7 ;清屏宏调用
LEA DI,CAR ;DI指向字符图形表
MOV DH,10 ;从第5行5列位置开始显示汽车
MOV DL,0
CALL MOVE_SHAPE
RET
QICHE ENDP
MOVE_SHAPE PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
MOV AH,0FH ;取当前显示方式
INT 10H
SUB CH,CH
MOV CL,[DI] ;CL放字符个数
INC DI ;DI指向字符图形表中的第一个字符
MOV CHAR_CNT,CX
MOV POINTER,DI
MOV LINE_ON,DH
MOV COL_ON,DL
PLOT_NEXT:
ADD DH,[DI+2] ;改变行列坐标
ADD DL,[DI+3]
CMP DL,80 ;出屏否?
JB MOV_CRSR
Pop DI
Pop DX
Pop CX
Pop BX
Pop AX
jmp exit2
MOV_CRSR:
MOV AH,2
INT 10H
MOV AL,[DI] ;取字符值
MOV BL,[DI+1] ;取字符属性
PUSH CX
MOV CX,1
MOV AH,09 ;显示字符
INT 10H
POP CX
ADD DI,4 ;DI指向下一个字符
LOOP PLOT_NEXT
CALL DLY
CALL ERASE
JMP SHORT PLOT_NEXT
exit2: ret
MOVE_SHAPE ENDP
ERASE PROC NEAR
MOV CX,CHAR_CNT
MOV DI,POINTER
MOV DH,LINE_ON
MOV DL,COL_ON
ERASE_NEXT:
ADD DH,[DI+2] ;修正光标的行坐标
ADD DL,[DI+3] ;修正光标的列坐标
MOV AH,2
INT 10H ;设置光标位置
MOV AL,[DI] ;以黑色的相同字符覆盖原有的图案实现擦除图案的功能
MOV BL,0 ;设置字符属性为0,黑色
PUSH CX
MOV CX,1 ;设置显示字符次数为1
MOV AH,9
INT 10H ;9号调用,显示黑色字符,擦除字符
POP CX
ADD DI,4 ;指向下一个要用来擦除的字符LOOP ERASE_NEXT
LOOP ERASE_NEXT
MOV CX,CHAR_CNT
MOV DI,POINTER
MOV DH,LINE_ON
INC COL_ON
MOV DL,COL_ON
RET
ERASE ENDP
CODE ENDS
END start
运行可执行程序CAR.exe,选择1,小鸟飞过;选择2,汽车开过;选择q,退出。
四、调试结果与分析
4.1 电路连接
一般无须连接电路,如果想要听到笑鸟鸣叫声大一点,可以把电脑里面的蜂鸣器接口用导线引出来,外接一个大的扬声器,效果可能好一点。
4.2 调试步骤
1)运行MF2KP汇编软件,在里面编辑源程序,编辑完成之后,生成.ASM文件,保存该该文件;
2)接着仍用上面的软件进行编译,连接,运行生成.EXE文件;
3)运行所生成的EXE文件即可产生所需要的结果。
程序正常运行截图如下面的几幅图像所示。
当点击开.EXE文件之后,出来一个界面,提示输入1,2或者q
(1)当输入为1时,得到了下面的用v组成的在“飞行”的大鸟。
且可以发出声音(声音程序部分可以跳过去,若将程序中的“;loop3”改成“loop3”则不发生):
(2)初始化图像
当按下按键2时,出现移动的小车:
(3)初始化图像
当按下按键2时,退出程序。
五、调试中出现的问题、原因及排除方法在编程调试的过程中,遇到了很多麻烦,总结起来有以下几点:
问题1:
当我们将程序start:mov ax,data
mov ds,ax
mov ah,0 ;设置显示方式为320*200彩色图形方式
mov al,3
中最后一句改成mov al,4,则组成的小鸟异动到屏幕左端会突然出现有一行v 显示不了的问题,而且整体的形状看起来也不稳定。
如下图
原因:mov al,4中不是文本格式
解决办法:改成文本格式,将4换成3或者0,1,2,3,6
如换成6之后对应的图形为:
问题2:
寄存器的值变幻无常,怎么办?
原因:程序结构过于复杂,使用寄存器比较频繁,以及使用了BIOS中断程序,这样会导致其它与之相关寄存器的值的改变。
解决办法:堆栈是保护环境的主要工具,一旦用错,后过将很严重,比如我们在调试程序的过程中,遇到过这样的问题:在一个函数的开始,我先用PUSH把所有寄存器入栈了,在函数的执行中,我又把一个寄存器PUSH到栈中保存,却忘记了在执行POP指令之前把它恢复出来!这样就造成了所有的寄存器的值都的生了变化,包括数据和代码段寄存器,这样不出问题才怪呢?!所以,要记住,PUSH了一个变量之后在新的PUSH来临之前如果又有POP别的变量的语句,一定会出问题!解决的办法只有一个,把PUSH和POP对上号。
问题3:
要显示的字符串过多,但又不想重复写代码,既要美观,又要易读,怎么办?
原因:过于频繁的调用中断显示字符串,导致程序过于庞大和复杂,可读性差。
解决办法:解决这种问题的最好方法是直接把显示部分写成子过程,但是子过程在传递参数的时候不方便,所以就用宏定义,宏定义可以很方便的传递参数,不仅使得程序美观好看,而且可读性好,程序代码紧凑。
问题4:
跳转,转移指令跳出的范围太大,编译出现错误怎么办?
原因:程序结构过于复杂,庞大。
解决办法:使用过程,也就是子程序设计,直接把一个要频繁要用到的函数
打包成一个子过程,然后用CALL调用子过程就可以了,这样就可以避免使用跳转和转移指令了。
六课程设计总结
这次的微机原理研讨实验实际上编程真的很复杂,我们自己完成很有难度,参考了一些网络上的程序,然后加上自己研讨的内容编出了程序,在运行过程也自己做了改动和验证。
其实汇编相对其他语言来说还是比较麻烦的语言,有很多固定格式的东西,有些繁琐。
这也造成了看起来很长的代码其实并没有很多实际的东西,理解起来并没有很多难度。
这次的研讨虽然都有讨论和交流,可是我主要做的是上台讲ppt,钟远宁主要是编程和调试,周佳琳是ppt的制作,我们三个一起做好的这次研讨实验。
这不仅验证了我们对知识的理解,也锻炼了我们的团队协作精神,还有上台演讲的能力,当然是对我来说的。
通过这次研讨让我们都知道自己的不足,做到了学以致用,更好的利用自己的知识去做一些实际的东西了。