汇编语言课设图形设计程序Word文件下载.doc
《汇编语言课设图形设计程序Word文件下载.doc》由会员分享,可在线阅读,更多相关《汇编语言课设图形设计程序Word文件下载.doc(37页珍藏版)》请在冰点文库上搜索。
所以最终采用的是方案三。
2.编程思想
在程序设计时采用先整体再分块,模块化编程的思想。
首先整体设计出程序的框架,写好主程序。
再分模块写好各个子函数。
调试好一个功能后再去编写下一个模块。
主函数的主体是一个分支选择程序。
包含了三个绘图模块圆,三角,矩形的数据定义和分支入口程序段。
而三个绘图子模块中又各自包含了若干子函数。
同时为了使程序紧凑,还编写了一些各个子模块公共使用的子函数。
程序概要框架图如下
图1:
程序概要框架图
3.程序设计
3.1 主程序设计
主程序主体是一个分支选择程序,包含了提示菜单,输入部分和选择部分。
采用MOVAH,9INT21H中断在屏幕上输出提示信息。
MOVAH,1INT21H从键盘输入一个字符将它的存在AL中再与1,2,3,q相比较跳转到响应的子函数入口程序段中。
同时还设计了检验输入的程序段再输入不为1,2,3q,时将自动跳转提示重新输入。
图2:
主程序流程图
3.2矩形子程序设计
在矩形子程序中采用写像素点的方法,点动成线将四条线一条一条的画出来。
首先提示输入信息输入矩形的长和宽。
调用一个输入函数将输入数据以16进制的方式存入AX中,再转存到L_S,W_S中。
之后将屏幕的模式设为图像模式640*480*16色,将长和宽一次存入CX中采用循环LOOP指令。
保持X不变Y依次增加或者Y不变X依次增加将四条直线一一画出。
同时为了使显示效果更好一些对线条进行了加粗,宽度为两个像素。
为了使程序结构清晰编写了WRITE_PIXEL宏指令,每调用一次就画出一个点。
而且可以认为的设定点的位置颜色等。
在函数中还加入了延时子程序,每画完一个点之后就调用一个延时子程序。
这样就可以在屏幕上实现动态显示。
在这部分的程序设计中也是采用模块化的思想,先画出一条直线。
改变参数就可以画出另外的三条直线。
同时在屏幕模式设定时也编写宏指令SETMODE。
调用的宏指令如下
WRITE_PIXELMACROPAGE1,ROW,COLUMN,COLOR
MOVAH,0CH
MOVAL,COLOR
MOVBH,PAGE1
MOVDX,ROW
MOVCX,COLUMN
INT10H
ENDM
SETMODEMACROMODE1
MOVAH,0
MOVAL,MODE1
子程序流程图如下
图3:
矩形子程序流程图
3.3三角形子程序设计
在三角形绘制中程序也分为几个部分,首先是三个顶点的输入子程序。
然后将三个顶点压栈,再调用Bresenham画线子程序。
在Bresenham画线子程序中依次调用写像素子程序和延时子程序实现三条线段的动态显示。
三角部分整体程序框架图如
图4:
三角子程序框架图
Bresenham画线算法是绘制三角形的核心程序,分析如下
Bresenham算法是计算机图形学中为了“显示器(屏幕或打印机)系由像素构成”的这个特性而设计出来的算法,使得在求直线各点的过程中全部以整数来运算,因而大幅度提升计算速度。
Bresenham算法是计算机图形学领域使用最广泛的直线扫描转换方法。
其原理是过各行、各列像素中心构造一组虚拟网格线,按直线从起点到终点顺序计算直线各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。
该算法的优点在于可以采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列所求的像素。
例如对于直线方程Y=kX+b;
A:
0<
K<
1时候的算法
1:
输入线段的两个端点Point1和Point2,并且存储到Point1(x1,y1)和Point2(x2,y2)中;
2:
将Point1载入桢缓存,绘画第一个起始点;
3:
计算常量△x、△y、2△y和2(△y-△x),并且获得一个决策参数的第一个值:
P=2△y-△x;
4:
从n=0开始,在沿线经过每个Xn处,进行下面的检测:
如果Pn<
0,下一个点绘制的是(Xn+1,yn),并且Pn+1=Pn+2△y
如果P0>
=0,下一个点绘制的是(Xn+1,Yn+1),并且Pn+1=Pn+2(△y-△x)
5:
重复执行△x-1次步骤4;
B:
斜率k=1或斜率k=0时候的算法
对于斜率等于0或者斜率等于1时候,不需要通过算法直接的对于其中单一坐标变量进行处理。
C:
斜率k<
0的情况算法
将起始点和中止点坐标Point1和Point2交换,可以转化到斜率为0和1之内的算法去实现。
3.3圆形子程序设计
图5:
圆形子程序框架图
在圆绘制模块中同样是采用Bresenham画线算法。
先由键盘输入圆半径,再设置成图形模式。
在调用圆Bresenham子程序将相关点堆栈,然后再调用圆画点子程序在屏幕上下左右四个点上向两边同时开始画点。
每画一个点就调用一下延时子程序实现绘图的动态显示。
3.4公共使用子程序设计
为了使程序结构较清晰,将三个子模块和主函数共同使用的子函数统一编写。
它们是数据输入子函数READ可以讲键盘输入的数据转化为16进制存在AX中。
在各个子函数的数据输入模块都是调用的这个子函数。
还有写像素子函数PIXEL。
它的作用是把经过Bresenham算法堆栈的数据用写像素的方法写在屏幕上。
延时子函数DELAY它的作用是延时使图像动态显示。
清屏CLEAR它的作用是调背景色清屏。
便于在图形模式和文字模式之间进行转换。
在其中的延时子程序采用了双层循环的方法,因为各个子程序运行用时不同为了便于调试和取得更好的效果。
不同的子模块对应不同的延时子程序。
4.硬件原理
显示器有字符显示模式和图形显示两种工作方式
在图形方式下的屏幕由一个一个的像素做成。
通过读写屏幕上的各个像素就
可以显示出各种各样的图形。
在汇编语言中提供了多种图形显示模式。
设置模式的方法是:
AL=模式号,AH=00H,然后通过BIOS功能调用INT10H来实现。
表1常见的图形显示模式
显示模式号
分辨率
色彩数
适用显卡
0DH
320*200
16
EGAVGA
OEH
640*200
0FH
640*350
2
10H
11H
640*480
MCGAVGA
12H
VGA
13H
256
VGA显卡上256KB显存,被划分为4个64KB的位平面。
比如屏幕上像素的位置是(X,Y),则改像素在显存位平面中字节地址的计算公式为:
字节地址=A0000H+Y*(640/8)+XMOD8(屏幕中有640列,每字节8位)
5.调试结果
图6:
主菜单截屏
矩形绘制输入长168,宽100
图7:
矩形截屏
三角形输入
图8:
三角形截屏
图9:
圆形截屏
结束语
这次的微机课设用的时间很久,从接到题目分析。
到后来的程序编写调试费了很多的功夫。
收获很多,一方面是专业知识。
计算机怎么来显示图形,显存是怎么工作的。
怎样将内容直接写到内存中在屏幕上反映出来。
对这些知识有了更深入的了解,同时对于分支选择程序。
子程序的调用压栈出栈断点保护有了更深入的理解。
在程序就要调试完成的时候突然发现了一个致命的错误。
画完圆之后无法再画矩形。
为了排查这个问题花了好长的时间一直没有解决。
后来经过请教同学和仔细的思考后发现。
在画圆程序中使用过CX,而在画矩形时矩形的大小是由CX来决定的。
虽然前面加入了压栈出栈,但是CX值已经被改变了。
再写入数据后只是把低位覆盖高位仍然是有数据的。
就造成了程序的错误。
类似这样的错误还有很多。
调试程序的过程也是一个不断检测错误不断反思的过程。
而且通过这次课设更是深入的体会到汇编语言做为底层语言在速度和大小方面有着很强的优势。
程序很小但是运行速度很快,功能能够实现的也很多。
更重要的是可以直接的控制计算机的硬件。
在另一方面的收获就是兴趣也许在一开始时是很重要的,之后让人坚持下去的就是克服困难的勇气和决心。
为了让程序的功能更加的多样化,我尝试着在其中添加各种各样的子程序。
大部分的想法都实现了,可以画出任意的三角,矩形和圆。
但是原本设想的图形移动和加入声音因为时间的原因没有再做。
算是一点遗憾吧。
在这次课设中自己也犯了一个错误,写比较大的程序时最好是和别人分工合作。
相互讨论这样做的会更加完美一些,特别是在程序调试时有人商量一下是很好的可以发现一些自己不容易发现的问题和错误。
在这方面因为其他人想做别的题目所以没有这么做。
总的来说收获很多,想起了以前上的一门选修课。
夏老师讲的先整体再部分来设计系统。
还有对问题的思考方法在这次课设中让我少走了很多弯路。
参考文献
1.新编汇编语言程序设计,杨文显
2.微机原理与接口技术,周佩玲
3.80X86汇编语言程序设计,王元珍
4.汇编程序三角形画法,李永飞
附录1
主序代码部分
INCLUDEYLIB.H
DATASSEGMENT
;
***********************************************
主函数菜单使用的提示字符串
MESS1DB0DH,0AH,"
Welcomtomyprogram,I'
mGaolingxiao.NO.:
0120911350101$"
MESS2DB0DH,0AH,"
Pleaseinputanumber(1--3)tochoseaprogram:
$"
MESS3DB0DH,0AH,"
Press1todrawasquareness$"
MESS4DB0DH,0AH,"
Press2todrawatriangle$"
MESS5DB0DH,0AH,"
Press3todrawacircle$"
MESS6DB0DH,0AH,"
Yourchoice:
$"
MESS7DB0DH,0AH,"
Press0tomainmeue,pressqtoquit:
MESS8DB0DH,0AH,"
sorry!
Inputerroe.$"
MESS9DB0DH,0AH,"
Pressqtoquit$"
各个子函数公共使用的数据定义部分
COLORDW02
BKCOLORDW0 ;
黑色为0
BUFFERDB6,?
6DUP(?
);
输入函数暂存buffer
C10DW10
圆用的数据段定义和提示语
MESS1_CDB0DH,0AH,"
Pleaseinputtheradius(1--200):
OL_CDB?
;
保存原来屏幕格式用
XDW280 ;
圆心位置
YDW240
RADIUSDW150 ;
半径长度
矩形用的数据段定义和提示字符串
OL_SDB?
;
矩形的原来图像模式
X_SDW50 ;
矩形的起始坐标
Y_SDW50 ;
L_SDW?
W_SDW?
COLOR_SDB2
MESS1_SDB0DH,0AH,"
Pleaseinputthelength(1--500):
MESS2_SDB0DH,0AH,"
Pleaseinputthewidth(1--500):
MESS3_SDB0DH,0AH,"
Press0tomainmenu,1todrawagain,otherkeytoquit.$"
三角用的数据段定义和提示字符
POINTDB24,?
24DUP(?
)
OL_TDB?
MESS1_TDB0DH,0AH,"
Pleaseinputthefristpoint$"
MESS2_TDB0DH,0AH,"
Pleaseinputthesecondpoint$"
MESS3_TDB0DH,0AH,"
Pleaseinputthethirdpoint$"
MESS5_TDB0DH,0AH,"
X:
MESS6_TDB0DH,0AH,"
Y:
MESS7_TDB0DH,0AH,"
Inputerror$"
DATASENDS
STACKSSEGMENT
DW100DUP(0)
STACKSENDS
CODESSEGMENT
ASSUMECS:
CODES,DS:
DATAS
START:
MOV AX,DATAS
MOV DS,AX
LEA DX,MESS1
MOV AH,9
INT 21H
;
显示主菜单提示字符串
***********************************************
DISPLAY:
LEA DX,MESS2
LEA DX,MESS3
LEA DX,MESS4
LEA DX,MESS5
LEA DX,MESS9
LEA DX,MESS6
主菜单选择部分
INPUT:
MOV AH,1
CMP AL,'
1'
JB DISPLAY
JE SQUAR
2'
JE TRIA
3'
JE CRIC
q'
JE OUTPUT
JMP DISPLAY
SQUAR:
;
矩形子程序的入口部分
CALL SQUAR_P
JMP OUTPUT
TRIA:
三角子程序的入口部分
CALL TRIA_P
CRIC:
圆形子程序的入口部分
CALL CRIC_P
OUTPUT:
;
退出程序段
INT 21H
MOV AH,4CH
INT 21H
***********************************************
方块绘制子程序段
SQUAR_PPROCNEAR
PUSH CX
LONG:
输入矩形的长度部分
LEA DX,MESS1_S
XOR AX,AX
CALL READ ;
调用输入子函数数据放在AX
CMP AX,0
JB LONG_ER
CMP AX,01F4H
JA LONG_ER
MOV WORDPTR[L_S],AX
JMP WIDTH_S
LONG_ER:
;
在输入错误时的程序段
CALL INPUT_ER
JMP LONG
WIDTH_S:
输入矩形的宽度部分
LEA DX,MESS2_S
MOV AH,9
CMP AX,0
JB WIDTH_ER
JA WIDTH_ER
MOV WORDPTR[W_S],AX
MOV AH,0FH
INT 10H
MOV OL_S,AL
SETMODE12H ;
设置640*480*16图形模式
XOR CX,CX ;
将CX清零,防止干扰
MOV CX,WORDPTR[L_S]
MOV DX,Y_S
JMP L1_S
WIDTH_ER:
JMP WIDTH_S
L1_S:
画第一条直线
PUSHCX ;
压栈保护
WRITE_PIXEL0,Y_S,X_S,COLOR_S;
调用写像素的宏命令
CALL DELAY_S ;
延时实现动态效果
INC X_S
POP CX
LOOP L1_S ;
循环画点
XOR CX,CX
MOV CX,WORDPTR[W_S] ;
将宽度存入CX
L2_S:
PUSH CX ;
画第二条直线
WRITE_PIXEL0,Y_S,X_S,COLOR_S
CALL DELAY_S
INC Y_S
POP CX
LOOP L2_S
XOR CX,CX
L3_S:
画第三条直线
PUSH CX
DEC X_S
LOOP L3_S
MOV CX,WORDPTR[W_S]
L4_S:
画第四条直线
DEC Y_S
LOOP L4_S
MOV AH,0
INT 16H
MOV AH,0
MOV AL,OL_S ;
恢复原来屏幕格式
LEA DX,MESS3_S ;
提示菜单信息
JE LONG
0'
JE DISPLAY
JE OUTPUT
JE OUTPUT
RET
SQUAR_PENDP
三角绘制子程序
TRIA_PPROCNEAR
CALL INPUT_T
MOV AH,0FH
MOV OL_T,AL ;
保存原来屏幕格式,用来恢复的
MOV AX,0A000H ;
显存
MOV ES,AX
SETMODE12H