汇编入门与精通.ppt

上传人:小飞机 文档编号:6388960 上传时间:2023-10-26 格式:PPT 页数:77 大小:224KB
返回 下载 相关 举报
汇编入门与精通.ppt_第1页
第1页 / 共77页
汇编入门与精通.ppt_第2页
第2页 / 共77页
汇编入门与精通.ppt_第3页
第3页 / 共77页
汇编入门与精通.ppt_第4页
第4页 / 共77页
汇编入门与精通.ppt_第5页
第5页 / 共77页
点击查看更多>>
资源描述

《汇编入门与精通.ppt》由会员分享,可在线阅读,更多相关《汇编入门与精通.ppt(77页珍藏版)》请在三一办公上搜索。

1、第九章 BIOS和DOS中断,1 BIOS与DOS中断调用概述 2 键盘I/O程序设计3 显示器I/O程序设计4 BIOS及DOS的时间功能调用,BIOS与DOS中断调用概述,在实际应用中,PC机与外部设备的传送数据大部分采用中断方式来实现,在主机系统主板上较高地址的ROM中,驻留着基本输入/输出系统(basic input/output system BIOS)的程序,它提供了系统加电自检、引导并装入操作系统、主要的I/O设备的处理程序等功能。用户可在不必了解中断服务程序的内部结构的基础上来使用中断服务程序。DOS是磁盘操作系统,是由BIOS在开机后自动装入内存的,DOS中断是建立在BIOS

2、之上的中断,它借用了BIOS软中断的功能来调用系统的中断服务程序。,键盘I/O程序设计,1.基础知识 键盘是计算机最基本的输入设备,键盘上的键主要分成三种基本类型键:字符键、功能键、组合控制键。(1)字符码与扫描码 键盘上的每一个键都有一个按位置进行的编码:扫描码,用户每按下一个键,都会产生一个键盘中断,BIOS中的键盘中断处理程序根据读到的扫描码就能唯一确定按下了哪个键。如果按下的是字符键,键盘处理程序求出对应的ASCII码,把扫描码和ASCII码一起存入一个BIOS定义的键盘缓冲区中;如果按下的不是字符键,就把扫描码和一个全0字节一起存入键盘缓冲区。,(2)键盘缓冲区 由于所按键并不会马上

3、被用户读取,所以在BIOS的参数区中,定义了一个键盘输入缓冲区,它的位置在内存0040:001AH处,结构如下:0040:001A BUFF_HEAD DW?;首指针 0040:001C BUFF_TAIL DW?;尾指针 0040:001 KB_BUFFER DW 16 DUP(?);16个字的缓冲区 0040:001 KB_BUFFER_END LABEL WORD;尾地址,2.BIOS键盘功能调用 BIOS提供的键盘中断类型号为16H,它的中断处理程序又分为3个功能,通过AH中的功能号来选择。(1)0号功能从键盘读入字符 输入参数:AH=0 返回结果:AH=键入字符的扫描码 AL=键入字

4、符的ASCII码(如按下的是字符键)或AL=0(如按下的是其它键)0号功能读键盘是强制读。,例:从键盘读一字符,把扫描码存到KEY1单元,ASCII码存到KEY2单元。MOV AH,0 INT 16H MOV KEY1,AH MOV KEY2,AL,(2)1号功能读键盘缓冲区的字符 输入参数:AH=1 返回结果:ZF=0时,AH=扫描码,AL=字符的ASCII码或0 ZF=1时表示无键按下,键盘缓冲区为空,1号功能读键盘是探测读。例如:在一程序中,加入一段指令序列,检测是否按下了ESC键,如果按下,则退出程序,否则,继续执行程序。加入的指令序列如下:MOV AH,1;1号功能 INT 16H;

5、BIOS的读键盘缓冲区的字符 JZ CONT;ZF=1,无键按下继续执行程序 CMP AH,01H;ZF=0,有键按下,判是ESC键的扫描码?JZ EXIT;是ESC键的扫描码退出程序 CONT:;继续执行程序 EXIT:;退出程序,(3)2号功能读键盘状态字节 输入参数:AH=2 返回结果:AL=键盘状态字节 键盘上有一些控制键和状态键,如Shift、Ctrl、Alt、NumLock、Scroll、Ins和CapsLock等,当按下这些键时,键盘处理程序并不返回扫描码,而是设置键盘状态字节的相应位。键盘状态字节如下图所示:,【例1】编写程序,当无键按下时,循环等待,当有键按下时,从键盘读10

6、个按键,并将其扫描码和字符码保存到内存单元中。(1)分析 1)利用INT 16H的1号功能为探测读键盘,当无键按下时循环等待,当有键按下时读键。2)利用INT16H的0号功能读取10个键的扫描码和字符码并保存到内存单元中。,DATA SEGMENTSTRING DB 20 DUP(?)DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATAMAIN PROC FAR MOV AX,DATA;初始化DS MOV DS,AXL1:MOV AH,1;利用INT 16H的功能1探测读键盘 INT 16H JZ L1;无键按下则循环 LEA SI,STRING MOV C

7、X,10,L2:MOV AH,0;用INT 16H的功能0读键盘 INT 16H MOV SI,AL;保存字符码 MOV SI+1,AH;保存扫描码 ADD SI,2 LOOP L2;循环10次MOV AX,4C00H INT 21HMAIN ENDPCODE ENDSEND MAIN,3.DOS键盘功能调用 上面介绍了BIOS键盘功能调用(16H),而在实际应用中,对于一般的键盘操作,最好使用对硬件依赖更少、更为方便的DOS键盘功能调用。下表中列出了DOS功能调用INT 21H中与键盘输入有关的功能调用。,【例2】编写一程序,从键盘输入一字符,若为“Y”,则从键盘接收一个字符串;若为“N”,

8、则结束程序;若都不是则循环读键盘。(1)分析:1)调用INT 21H的1号功能从键盘读入一个字符。2)若键入的字符为Y,则调用INT 21H的0AH号功能从键盘输入一个字符串。(2)程序流程图如下:,DATA SEGMENT STRING DB 20,?,20 DUP(?);定义存放字符串的缓冲区DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATAMAIN PROC FARSTART:MOV AX,DATA MOV DS,AXLOP1:MOV AH,1;从键盘读入一个字符 INT 21H CMP AL,Y;若为“Y”,转输入字符串程序段 JZ IN_STRI

9、NG CMP AL,N;若为“N”,结束程序 JZ EXIT JMP LOP1;若都不是,循环读键盘字符IN_STRING:LEA DX,STRING;从键盘输入一字符串 MOV AH,0AH INT 21HEXIT:MOV AX,4C00H INT 21HMAIN ENDPCODE ENDS END START,显示器I/O程序设计,显示器通过显示适配器(显示卡)与PC机相连,显示卡是计算机和显示器的接口,现在常用的显示卡都支持字符显示和图形显示两种方式,每种显示方式还有多种显示模式。字符方式也称为文本方式,在这种显示方式下,屏幕上只能显示字符及其属性。字符通常是指字母、数字、符号和一些简单

10、的图形(如菱形、笑脸符等)。在字符方式下,屏幕被划分为若干行和列,较典型的是80列25行。显示字符有两种方法,一种是用BIOS和DOS功能调用,另一种是直接组织显示缓冲区。,显示的基础知识,(1)显示模式 在字符方式下包括几种显示模式,每种模式具有不同的分辨率和颜色,如下表所示。其中用得最普遍的是显示模式3,在这种模式下,显示器的屏幕被划分成80列(0-79)25行(0-24),可以用列号和行号组成的坐标来表示屏幕上的每个可显示位置,如左上角的坐标为(0,0),右下角的坐标为(79,24)。,BIOS显示功能调用,BIOS中提供的显示调用INT 10H功能如下:AH=0:设置显示模式 输入参数

11、:AL=显示模式号(表8-10 常见的字符显示模式)返回结果:无返回参数,只是屏幕设置为指定的模式AH=1:设置光标类型输入参数:(CH)4=0,光标显示,(CH)0-3=光标起始线(CL)0-3=光标结束线,(CH)4=1,光标不显示(关闭)返回结果:无,AH=2:设置光标位置 输入参数:BH=页号(一般为0)DH=新光标的行号 DL=新光标的列号 返回结果:无 AH=3:读光标位置 输入参数:BH=页号(要显示的当前页号)返回结果:CH=光标开始线,CL=光标结束线 DH=光标当前行号,DL=光标当前列号,AH=5:选择当前显示页输入参数:AL=选择的页号 返回结果:无AH=6:屏幕初始化

12、或向上滚动 输入参数:AL=要滚动的行数,AL=0,全屏滚动(清屏)CH=滚动窗口左上角行号,CL=滚动窗口左上角列号 DH=滚动窗口右下角行号,DL=滚动窗口右下角列号 BH=滚入行属性 返回结果:无,AH=7:屏幕初始化或向下滚动 输入参数:AL=要滚动的行数,AL=0,全屏滚动(清屏)CH=滚动窗口左上角行号,CL=滚动窗口左上角列号 DH=滚动窗口右下角行号,DL=滚动窗口右下角列号 BH=滚入行属性 返回结果:无AH=8:读光标位置的属性和字符 输入参数:BH=显示页 返回结果:AH=光标位置的属性 AL=光标位置的字符,AH=9:在光标位置显示字符及属性 输入参数:BH=显示页 B

13、L=字符的属性 AL=待显示字符的ASCII码 CX=字符重复次数(只显示一个字符时,CX=1)返回结果:无 AH=0AH:在光标位置只显示字符,不改变属性 输入参数:BH=显示页 AL=待显示的字符 CX=字符重复次数(只显示一个字符时,CX=1)返回结果:无,AH=0EH:显示字符且光标自动前移 输入参数:AL=要显示的字符 BL=前景色 返回结果:无 AH=0FH:获取当前的显示模式 输入参数:无 返回结果:AL=当前显示模式号 AH=当前显示模式每行的列数 BH=当前显示页号,AH=13H:显示字符串输入参数:ES:BP=字符串首地址 CX=串长度DH,DL=起始行、列号BH=显示页号

14、AL=0,BL=属性,光标保持在原处,串由字符组成,仅显示字符 AL=1,BL=属性,光标到串尾,串由字符组成,仅显示字符AL=2,光标保持在原位不动,串由字符及属性组成AL=3,光标到串尾,串由字符及彩色字符属性和背景属性(两个属性由一个字节决定)组成 返回结果:无,【例3】在屏幕中间建立一个34列11行反相显示的小窗口,在窗口最上面一行以青底淡红字显示一个菜单栏:File Edit Search View Options Help,在屏幕最下面一行再显示该菜单栏,但每一项属性不同。,(1)分析1)在屏幕中间建立一个34列11行反相显示的小窗口,应调用INT 10H的6号功能,定义左上角坐标

15、为(7,23),右小角坐标为(17,56),即屏幕中间大小为34列11行的小窗口,把小窗口清为白底黑字的属性即为反相显示,指令序列如下:MOV AH,6;调用INT 10H的6号功能MOV AL,0;AL=0,全屏滚动(清屏)MOV CH,7;CH=滚动窗口左上角行号7MOV CL,23;CL=滚动窗口左上角列号23MOV DH,17;DH=滚动窗口右下角行号17MOV DL,56;DL=滚动窗口右下角列号56MOV BH,70H;白底黑字,反向显示INT 10H,2)在窗口最上面一行显示一个菜单栏,应调用INT 10H的功能13HMOV AH,13H;INT 10H的功能13H,在窗口最上面

16、一行显示菜单栏LEA BP,STRING1;BP字符串SRING1的首地址MOV CX,ST1_LEN;CX=串长度ST1_LENMOV DH,7;DH=起始行号7MOV DL,23;DL=起始列号23MOV BH,0;BH=显示页号,一般为0MOV AL,1;光标到串尾,串由字符组成,仅显示字符MOV BL,3CH;字符属性为青底淡红色INT 10H,DATA SEGMENTSTRING1 DB File Edit Search View Options Help;窗口上面待显示的字符串ST1_LEN EQU$-STRING1;显示串1的长度STRING2 DB F,1ch,i,1ch,l,

17、1ch,e,1ch,20h,1ch;窗口下面待显示的字符串 DB E,4ah,d,4ah,i,4ah,t,4ah,20h,4ah DB S,2dh,e,2dh,a,2dh,r,2dh,c,2dh,h,2dh,20h,2dh DB V,5ah,i,5ah,e,5ah,w,5ah,20h,5ah DB O,3eh,p,3eh,t,3eh,i,3eh,o,3eh,n,3eh,s,3eh,20h,3eh DB H,6bh,e,6bh,l,6bh,p,6bhST2_LEN EQU($-STRING2)/2;显示串2的长度DATA ENDS,CODE SEGMENT ASSUME CS:CODE,DS:D

18、ATA MAIN PROC FAR MOV AX,DATA;设置DS=ES MOV DS,AX MOV ES,AX MOV AH,0;设置显示模式3 MOV AL,3 INT 10H,MOV AH,6;清屏MOV AL,0 MOV CH,0;屏幕左上角坐标MOV CL,0MOV DH,24;屏幕右下角坐标MOV DL,79MOV BH,07;属性INT 10HMOV AH,1;暂停,等待键盘输入单个字符 INT 21HMOV AH,6;建立小窗口MOV AL,0;全屏滚动MOV CH,7;左上角坐标MOV CL,23MOV DH,17;右下角坐标MOV DL,56,MOV BH,70H;白底黑

19、字,反向显示INT 10HMOV AH,13H;在窗口最上面一行显示菜单栏LEA BP,STRING1;ES:BP字符串首地址MOV CX,ST1_LEN;CX=串长度MOV DH,7;DH,DL=起始行,列位置MOV DL,23MOV BH,0MOV AL,1MOV BL,3CH;属性为青底淡红色INT 10H MOV AH,1;暂停INT 21H;在窗口最下面一行以多种属性显示菜单栏,MOV AH,13H;INT 10H的功能13HLEA BP,STRING2;串首地址MOV CX,ST2_LEN;显示串的长度MOV DH,17;起始位置行号MOV DL,23;起始位置列号MOV BH,0

20、 MOV AL,3;光标到串尾,串由字符及属性组成INT 10HMOV AH,4CH;返回DOSINT 21HMAIN ENDPCODE ENDS END MAIN,(4)程序说明:INT 10H的13H号功能有四种显示字符串的方式,前两种方式(AL=0,1),整个字符串只能以一种属性显示,后两种方式(AL=2,3)每个字符都可以不同属性显示。本程序中,显示窗口上面的菜单栏用AL=1的方式,显示字符的属性相同;显示窗口下面的菜单栏用AL=3的方式,每个字符以不同的属性显示。(5)执行结果如下图:,3.DOS显示功能调用 DOS的INT 21H提供的显示功能调用如下:AH=2,显示一个字符,光标

21、跟随字符移动,检测Ctrl_Break 输入参数:DL=待显示字符的ASCII码 返回结果:无AH=6,显示一个字符,光标跟随字符移动,不检测Ctrl_Break 输入参数:DL=待显示字符的ASCII码 返回结果:无AH=9,显示字符串,光标跟随字符串移动 输入参数:DS:DX=待显示字符串的首地址,字符串必须以$结尾。返回结果:无,用INT 21H的9号功能显示一个字符串,首先要在数据段中定义一个待显示的字符串,这个字符串必须以$结尾。例如,定义一个字符串如下:STRING DB HOW ARE YOU,0DH,0AH,$然后,在代码段中,显示该字符串的指令为:LEA DX,STRING

22、MOV AH,9 INT 21H,【例4】用DOS时间功能调用获取当前时间,并在屏幕上显示出来。(1)分析1)本程序首先调用DOS时间功能调用(INT 21H的2CH功能),读取系统当前时间:MOV AH,2CHINT 21H执行后的返回结果:CH=小时(0-23)CL=分钟(0-59)DH=秒(0-59)2)然后按照一定的格式显示出来,其中需要多次把返回的二进制数结果转换成十进制并显示出来,所以用子程序来实现这一功能。,(2)编写程序如下:DATA SEGMENT TIME DB CURRETN TIME IS$;定义一个提示串 DATA ENDS CODE SEGMENT ASSUME C

23、S:CODE,DS:DATA MAIN PROC FAR,LEA DX,TIME;显示提示串 MOV AH,9 INT 21H MOV AH,2CH;获取当前时间 INT 21H MOV AL,CH;显示小时数 CALL P1 MOV DL,3AH;显示一分隔符“:”MOV AH,2 INT 21H MOV AL,CL;显示分钟数 CALL P1 MOV DL,3AH;显示分隔符“:”MOV AL,2 INT 21H MOV AL,DH;显示秒数 CALL P1 MOV AX,4C00H;返回DOS INT 21HMAIN ENDP,;把寄存器中的内容转换成十进制显示出来P1 PROC;入口参

24、数:AL为待显示的寄存器 PUSH BX;PUSH DX XOR AH,AH;(1)做除法 MOV BL,10;把二进制转换成十进制 DIV BL MOV BL,AH;保存余数 MOV DL,AL OR DL,30H;把十位数转换成ASCII码 MOV AH,2;显示十位数 INT 21H MOV DL,BL OR DL,30H;把个位数转换成ASCII码 MOV AH,2;显示个位数 INT 21H POP DX POP BX RETP1 ENDPCODE ENDS END START,(3)程序说明:1)因为当前时间的小时数、分钟数和秒数都不会超过两位十进制数,所以这里把二进制数转换成十进

25、制时,只需做一次除法(除以10)即可,所得商和余数分别为十进制的十位数和个位数。,【例5】用BIOS时间功能调用获取当前日期,并在屏幕上显示出来。(1)分析:本程序与上例类似,调用BIOS时间功能调用(INT 1AH的功能4)获取当前日期并显示。不同之处在于,INT 1AH的功能4的返回结果是用压缩BCD码的形式表示的,因此转换成十进制并显示的程序段不同。1)首先调用BIOS时间功能调用(INT 1AH的功能4)获取当前日期:MOV AH,04H INT 1AH 执行后的返回结果:CF=1表示失败 CF=0表示成功 CX=年(1980-2099)DH=月(1-12)DL=日(1-31)2)IN

26、T 1AH的功能4的返回结果是用压缩BCD码的形式表示的,因此转换成十进制并显示的程序段不同。,2)编写程序如下:DATA SEGMENT DATE DB CURRETN DATE IS$;定义一个提示串 DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATAMAIN PROC FARSTART:MOV AX,DATA;初始化DS MOV DS,AX,LEA DX,DATE;显示提示串 MOV AH,9 INT 21H MOV AH,04H;获取当前日期 INT 1AH JC EXIT;若失败,则转EXIT PUSH DX;保存月、日;显示年份 MOV BX,

27、CX;BX=年份 MOV CX,4;年份4位,需循环4次L1:PUSH CX;(1)保存循环次数 MOV CL,4;循环左移取出BCD码 ROL BX,CL MOV DL,BL;把BL内容取到DL中 AND DL,0FH;屏蔽高四位 OR DL,30H;转换成ASCII码 MOV AH,2;显示一位 INT 21H,POP CX;恢复循环次数 LOOP L1 MOV DL,2DH;显示一分隔符“”MOV AH,2 INT 21H;显示月及日 POP BX;BX=月,日 MOV CX,4;循环四次 L2:PUSH CX;保存循环次数 MOV CL,4 ROL BX,CL;采用ROL方式取出BCD

28、码 MOV DL,BL;取到DL中 AND DL,0FH;清除高四位 OR DL,30H;转换成ASCII码 MOV AH,2;显示在屏幕上 INT 21H,POP CX CMP CX,3;(2)CX=3,显示分隔符“”JNZ L3 MOV DL,2DH;显示分隔符“”MOV AH,2 INT 21HL3:LOOP L2;循环4次EXIT:MOV AX,4C00H INT 21HMAIN ENDPCODE ENDS END START,图形系统程序设计,1.显示模式 在图形方式下,显示屏幕上由像素点组成,屏幕按分辨率划分成像素行和列。可以通过读写屏幕上的各个点的像素,显示出各种单色和彩色的图形

29、。在各种不同的显示模式下,屏幕显示的像素分辨率、颜色数以及显示存储器的组织方式都不同,与图形有关的显示模式及其适用的显示卡如下表所示。,用BIOS功能调用编写显示程序,INT 10H提供了两个图形方式下读写像素的功能:AH=0CH,写像素 输入参数:DX=像素行 CX=像素列 BX=显示页号 AL=像素颜色值 返回结果:无 AH=0DH,读像素 输入参数:DX=像素行 CX=像素列 返回结果:AL=像素颜色值,【例6】:编程实现,在屏幕上显示一个直角三角形,三边分别为红、黄、绿三种颜色。(1)分析:1)显示系统中默认的显示方式为文本方式,首先要读取当前的显示模式并保存,显示图形后再恢复原来的显

30、示模式。2)调用INT 10H的读写像素功能,分别画出三角形的三边。,CODE SEGMENT ASSUME CS:CODEMAIN PROC FAR MOV AX,0600H;利用INT 10H的功能6清屏 MOV BH,7;黑底白字 MOV CX,0;窗口左上角坐标(0,0)MOV DX,184FH;窗口右下角坐标(24,79)INT 10H MOV AH,0FH;读取当前的显示模式 INT 10H PUSH AX;压入堆栈保存 MOV AH,0;设置当前的显示模式为12H MOV AL,12H INT 10H,;(1)从坐标(200,200)处开始画一水平线 MOV CX,200;开始列

31、 MOV DX,200;开始行LOP1:MOV AH,0CH;写像素功能 MOV AL,0AH;浅绿色 MOV BH,0 INT 10H;写像素 INC CX;列坐标加1,准备画下一点 CMP CX,300;判断水平线是否结束 JNZ LOP1;未结束则循环,;(2)从坐标(200,200)处开始画一垂直线 MOV CX,200;开始列 MOV DX,200;开始行LOP2:MOV AH,0CH;写像素功能 MOV AL,0CH;淡红色 MOV BH,0 INT 10H DEC DX;行坐标减1,准备画下一点 CMP DX,100;判断垂直线是否结束 JNZ LOP2;未结束则循环;(3)从坐

32、标(200,100)处开始画一斜线 MOV CX,200;开始列 MOV DX,100;开始行,LOP3:MOV AH,0CH;写像素功能 MOV AL,0EH;黄色 MOV BH,0 INT 10H INC CX;行、列坐标同时加1,画斜线 INC DX CMP DX,200;判断斜线是否结束 JNZ LOP3 MOV AH,1;暂停 INT 21H POP AX;恢复原来的显示模式 MOV AH,0 INT 10H,EXIT:MOV AX,4C00H INT 21H MAIN ENDP CODE ENDS END MAIN(4)程序说明:1)从坐标(200,200)处开始向右画三角形的水平

33、线段,每写一个象素,列坐标加1,加到列坐标为300则停止。2)从坐标(200,200)处开始向上画三角形的垂直线段,每写一个象素,行坐标减1,减到行坐标为100则停止。3)从坐标(200,100)处开始画三角形的斜直线段,每写一个象素,行列坐标同时加1,加到列坐标为(300,200)则停止。,直接组织显示缓冲区(1)VGA的显示缓冲区 VGA显示卡的显示缓冲区容量为256KB,它除了兼容CGA、EGA的显示模式外,还提供了一种VGA独有的显示模式12H。这里主要以VGA的显示模式12H为例。VGA的显示模式12H,分辨率为640480,可显示16种颜色,把256KB的显存分成4个64KB的显示

34、页面。每个像素由4位来表示,每个页面一位,4个页面上的相应位确定屏幕上一个像素点的颜色,4个页面中的每个字节表示相邻的8个水平像素。所以,每个像素有16种颜色,要在屏幕上画出一个像素点,必须将一个像素的颜色写入显示缓冲区的4个页面。若屏幕上像素的位置由坐标(x,y)来表示,像素位置转换为显示缓冲区中位置的计算公式为:字节地址=A0000H+y80+x/8,图形控制器 在图形方式下,直接编写驱动VGA内部寄存器和显示缓冲区来处理图形程序,是相当复杂的,我们这里只介绍部分硬件结构和编程方法。在VGA的图形方式下,CPU和显示缓冲区之间不是直接传送数据的,而是在图形控制器的控制和处理下,经过锁存器来

35、传送的,每个页面对应一个8位的锁存器。图形控制器内部有10个寄存器,系统只分配了两个端口地址:3CEH和3CFH。其中3CEH为索引寄存器,3CFH中实际上有9个寄存器,共用一个端口地址。访问3CFH中的9个寄存器的方法是:首先把要访问的寄存器的编号(即索引值)写入索引寄存器3CEH中,选择其中的一个寄存器为当前活动寄存器,然后访问3CFH就是访问指定的寄存器。,3)VGA的读写模式 VGA显示卡提供两种读模式:读模式0和读模式1,其中读模式0是默认的模式。读模式0可以读取某个页面的字节,选择哪一个页面的字节读入CPU,取决于读映像选择寄存器。当希望读取多个页面的内容时,使用读模式1为更方便。

36、VGA提供了4种写模式,其中写模式0为直接处理器写,这是最常用的方式,也是图形控制器的缺省模式。在写模式0中,所写入的CPU数据可以更新一个或是全部的页面,同时,还可以与一个事先定义好的值进行逻辑运算,以更新锁存器中的8个像素或其中任一个像素。在这些操作中,要用到置位/复位寄存器、数据循环/功能选择寄存器和位屏蔽寄存器。(4)图形编程举例,【例7】用直接组织显示缓冲区的方法编程实现,在屏幕上显示一个直角三角形,三边分别为红、黄、绿三种颜色。(1)分析 本程序的主要步骤与上例相同,区别只是具体写每个象素的方法不同,上例通过调用BIOS显示例程INT 10H来读写像素,本例通过对硬件编程来直接组织

37、显示缓冲区。另外,为使程序简洁,计算像素的字节地址和位掩码以及写像素功能分别由子程序来实现。,CODE SEGMENT ASSUME CS:CODEMAIN PROC FAR MOV AX,0600H;清屏 MOV BH,7 MOV CX,0 MOV DX,184FH INT 10H;读取当前的显示模式并保存 MOV AH,0FH INT 10H PUSH AX;设置显示模式为12H,MOV AH,0 MOV AL,12H INT 10H;从(200,200)处开始画水平线 MOV CX,200 MOV DX,200LOP1:CALL GET_ADDR;1)计算像素的字节地址和位掩码 PUSH

38、 CX;保存CX中的坐标值 MOV CL,AH MOV CH,0AH;浅绿色 CALL WRITE0;(2)写像素 POP CX;恢复CX中的坐标值,INC CX;修改坐标 CMP CX,300;判断是否画完 JNZ LOP1;从(200,200)开始画垂直线 MOV CX,200 MOV DX,200LOP2:CALL GET_ADDR;计算像素的字节地址和位掩码 PUSH CX MOV CL,AH MOV CH,0CH;淡红色 CALL WRITE0;写像素 POP CX DEC DX CMP DX,100;判断是否画完 JNZ LOP2;从(200,100)处开始画斜线 MOV CX,2

39、00 MOV DX,100,LOP3:CALL GET_ADDR;计算像素的字节地址和位掩码 PUSH CX MOV CL,AH MOV CH,0EH;黄色 CALL WRITE0;写像素 POP CX INC CX INC DX CMP DX,200 JNZ LOP3MOV AH,1;暂停 INT 21H POP AX;恢复原来的显示模式 MOV AH,0 INT 10HEXIT:MOV AX,4C00H;返回DOS INT 21HMAIN ENDP,;计算像素的字节地址和位掩码子程序GET_ADDR PROC NEAR;入口:CX=X坐标,DX=Y坐标 PUSH CX;出口:BX=字节地址

40、,AH=位掩码 PUSH DX MOV AX,0A000H;设置段地址 MOV ES,AX MOV AX,80;AX=Y*80 MUL DX MOV BX,AX;BX=Y*80 MOV AX,CX;计算X/8 MOV CL,8 DIV CL MOV CL,AH;余数保存在CL中 MOV AH,0 ADD BX,AX;BX=Y*80+X/8 MOV AH,80H SHR AH,CL;AH=位掩码 POP DX POP CX RETGET_ADDR ENDP,;写像素子程序。;入口参数:BX=字节地址,CH=象素颜色值,CL=位掩码。WRITE0 PROC NEAR;出口参数:完成写一新象素 PU

41、SH ES;保护现场 PUSH AX PUSH BX PUSH DX PUSH CX;(2)写像素颜色值到置位/复位寄存器 MOV DX,3CEH;索引寄存器地址 MOV AL,0;置位/复位寄存器索引值 MOV AH,CH;像素颜色值 OUT DX,AX;写入寄存器;设置置位/复位允许寄存器为允许4个页面 MOV AL,1;置位/复位允许寄存器索引值 MOV AH,0FH;允许4个页面 OUT DX,AX;写入寄存器,;写位屏蔽码到位屏蔽寄存器MOV AL,8;位屏蔽寄存器索引值 MOV AH,CL;位屏蔽码 OUT DX,AX;写入 MOV AL,ES:BX;(3)读四个页面到锁存器 MO

42、V ES:BX,AL;写入新像素MOV AL,1;置位/复位允许寄存器 MOV AH,0;禁止4个页面 OUT DX,AX,MOV AL,8;设屏蔽寄存器 MOV AH,0FFH;允许8位写入 OUT DX,AX POP CX;恢复现场 POP DX POP BX POP AX POP ES RETWRITE0 ENDPCODE ENDS END MAIN,发声系统程序设计,1.扬声器的驱动系统 计算机上的扬声器是由可编程定时/计数器8253(8254)和并行接口芯片8255共同控制发声的,发声系统的结构如下图所示。在下图的扬声器驱动系统中,8255PB口第1位的输出与8253/54计数器2的

43、输出,这两个信号经过一个与门后,如果能输出一个连续的方波脉冲信号,经驱动器驱动后就可以使扬声器发声,控制方波的频率和持续时间就可以发出不同音高和音长的声音。因为与门有两个输入信号,只要使其中一个信号输出方波,另一个的输出保持为1状态,就可以使扬声器发声,因此,发声程序有两种设计方法,在前面的中介绍过直接控制8255的PB1输出,使扬声器发声的方法,这里介绍另一种方法。,对8253/54编程来使扬声器发声,另一种驱动扬声器发声的方式是使PB1为1,打开与门,由8253/54的计数器2输出方波。在编写发声程序时,首先要初始化8253/54(包括写控制字和计数初值),要计数器2输出方波,需工作在方式

44、3,此时控制字为0B6H。8253/54初始化后,使PB0和PB1为1,打开计数器2的门控信号端GATE2,计数器2开始工作,输出方波,同时与门也打开,方波信号驱动扬声器发声,延时一段时间后,关闭扬声器。,【例8】:编写利用8253/54驱动发声的通用发声子程序GENSOUND。入口参数:CX=发声的频率值,BX=持续的时间(ms)(1)分析:首先要初始化8253/54,即写入控制字和计数除值,然后打开与门和8253/54的门控信号GATE2,开始发声,延时一段时间后,关闭与门和门控信号,停止发声。,GENSOUND PROC NEAR PUSH DX MOV AL,0B6H;写8253/54

45、控制字 OUT 43H,AL MOV DX,12H;计算计数初值,结果在AX中 MOV AX,3208H DIV CX OUT 42H,AL;送计数初值低字节 MOV AL,AH OUT 42H,AL;送计数初值高字节 IN AL,61H;读入61H端口原值 MOV AH,AL;保存在AH中 OR AL,3;将第0、1位置1后送回61H端口 OUT 61H,AL,L2:MOV CX,0AB5EH;延时(BX)1msL3:LOOP L3 DEC BX JNZ L2 MOV AL,AH;恢复61H端口原值,停止发声 OUT 61H,AL POP DX RET GENSOUND ENDP,乐曲程序,

46、编写乐曲程序的方法是,根据乐谱中每个音符及其节拍,可以得到两个数据:每个音符的频率值和持续时间,通过调用通用发声子程序,就可以设计出演奏的乐曲程序。要设计乐曲程序,首先必须知道每个音符与发声频率的关系,表8-16给出了乐曲C调的频率值。其次,乐曲中音符的持续时间由乐曲的速度和每个音符的节拍数来确定。在4/4拍中,如果给全音符分配0.8秒的时间,则二分音符的持续时间为400ms,四分音符为200ms。在设计乐曲程序时,首先根据乐谱中每个音符及其节拍定义两个数据表:一个频率表和一个节拍时间表,然后依次取出表中的频率值和时间值,调用通用发声子程序,就可以编写出音乐演奏程序了。,音符和频率表 音符 频

47、率(Hz)音符 频率(Hz)音符 频率(Hz)低1 130.81 中1 261.63 高1 523.52 低2 146.83 中2 293.66 高2 587.33 低3 164.81 中3 329.63 高3 659.26 低4 174.61 中4 349.23 高4 698.46 低5 196.00 中5 392.00 高5 783.99 低6 220.00 中6 440.00 高6 880.00 低7 246.94 中7 493.88 高7 987.77,【例9】:根据下面给出的乐谱,设计乐曲演奏程序。1=C 4/4 1 2 3 1|1 2 3 1|3 4 5|3 4 5|56 54 3

48、 1|56 54 3 1|2 1|2 1|(1)分析 1)首先根据给出的乐谱,定义两个变量,变量FREQ中存放的是频率表,依次为每个音符对应的频率值;变量TIME中存放的是节拍时间表,依次为每个音符的持续时间。2)其次,依次取出两个表中的频率值和时间值,调用通用发声子程序,就可以,发出不同频率和音长的声音,完成乐曲程序了。,(2)编写程序如下:DATA SEGMENT FREQ DW 262,294,330,262,262,294,330,262,330,349,392 DW 330,349,392,392,440,392,349,330,262,392,440 DW 392,349,330,

49、262,294,196,262,294,196,262,-1 TIME DW 8 DUP(800),2 DUP(800,800,1600)DW 2 DUP(400,400,400,400,800,800)DW 2 DUP(800,800,1600)DATA ENDS,CODE SEGMENT ASSUME CS:CODE,DS:DATA MAIN PROC FAR START:MOV AX,DATA MOV DS,AX MOV SI,OFFSET FREQ;设SI为频率表指针 MOV DI,OFFSET TIME;DI为时间表指针 L1:MOV CX,SI;取频率值送CX CMP CX,-1;(1)若为-1则结束 JE EXIT MOV BX,DI;取持续时间送BX CALL GENSOUND;调用通用发声子程序 ADD SI,2 ADD DI,2 JMP L1,EXIT:MOV AX,4C00H INT 21H MAIN ENDP CODE ENDS END START(3)程序说明:变量FREQ中的最后一个数值1为结束标志,每取一个频率值,判断是否为1,若为1,表明表中的各个频率值都已取完,则退出程序。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号