890 likes | 1.15k Views
第 9 章 BIOS 和 DOS 中断调用程序设计. 9.1 键盘输入中断调用 9.2 显示器输出中断调用. 开 始. DOS 中断和 BIOS 中断. 在存储器系统中,内存从 0FE000H 高端 8K 的 ROM 中 存放有基本输入输出系统( Basic Input/Output System , BIOS )例行程序。 BIOS 给 PC 系列的不同微处理器提供了兼容的系统 加电自检、引导装入、主要 I/O 设备的处理程序以及接口控制等功能模块来处理所有的系统中断 。
E N D
第9章 BIOS和DOS中断调用程序设计 • 9.1键盘输入中断调用 • 9.2 显示器输出中断调用 开 始
DOS中断和BIOS中断 在存储器系统中,内存从0FE000H高端8K的ROM中存放有基本输入输出系统(Basic Input/Output System,BIOS)例行程序。BIOS给PC系列的不同微处理器提供了兼容的系统加电自检、引导装入、主要I/O设备的处理程序以及接口控制等功能模块来处理所有的系统中断。 使用BIOS功能调用,给程序员编程带来极大方便。程序员不必了解硬件的具体细节,可直接使用指令设置参数,并中断调用BIOS例行程序,所以利用BIOS功能调用编写的程序简洁,可读性好,而且易于移植
磁盘操作系统(Disk Operating System)是PC机上最重要的操作系统,它是由软盘或硬盘提供的。它的两个DOS模块IBMBIO.COM和IBMDOS.COM使BIOS使用起来更方便。因为DOS模块提供了更多更必要的测试,使用DOS操作比使用相应功能的BIOS操作更简易,而且DOS对硬件的依赖性更少些。 DOS模块和ROM BIOS的关系如下图所示。
DOS中断和BIOS中断使用方法 DOS功能调用与BIOS功能都通过软件中断调用。在中断调用前需要把功能号装入AH寄存器,把子功能号装入AL寄存器,除此之外,还需要在CPU的寄存器中提供专门的调用参数。一般来说,调用DOS或BIOS功能时,有以下几个步骤: (1)将调用参数装入指定的寄存器。 (2)如需功能调用号,把它装入AH。 (3)如需子功能调用号,把它装入AL。 (4)按中断号调用DOS或BIOS。 (5)检查返回参数是否正确。
表9.1 BIOS中断类型 地址(Hex) 类型码 中断名称 0—3 0 除以0 4—7 1 单步 8—B 2 非屏蔽 C—F 3 断点 10—13 4 溢出 14—17 5 打印屏幕 18—1B 6 保留 1D—1F 7 保留 20—23 8 定时器 24—27 9 键盘 28—2B A 保留的硬中断 2C—2F B 异步通信(COM2) 30—33 C 异步通信(COM1) 34—37 D 硬盘 38—3B E 软盘 3C—3F F 并行打印机 地址(Hex) 类型码 中断名称 40—43 10 视频显示I/O调用 44—47 11 设备检测调用 48—4B 12 存储器容量检测 4C—4F 13 软/硬盘I/O调用 50—53 14 通信I/O调用 54—57 15 盒式磁带I/O调用 58—5B 16 键盘I/O调用 5C—5F 17 打印机I/O调用 60—63 18 ROM BASIC 64—67 19 引导程序入口 68—6B 1A 时间调用 6C—6F 1B 键盘CTRL-BREAK控制 70—73 1C 定时器报时 74—77 1D 显示器参数表 78—7B 1E 软盘参数表 7C—7F 1F 字符点阵结构参数表 BIOS中断向量
地址(Hex) 类型码 中断名称 80—83 20 程序结束,返回DOS 84—87 21 DOS系统功能调用 88—8B 22 程序结束地址 8C—8F 23 CTRL_BREAK退出地址 90—93 24 标准错误出口地址 94—97 25 绝对磁盘读 98—9B 26 绝对磁盘写 9C—9F 27 程序结束,驻留内存 A0—FF 28—3F 为DOS保留 100—17F 40—5F 保留(扩充BIOS中断向量) 180—19F 60—67 为用户软中断保留 1A0—1FF 68—7F 不用(其中70—77为I/O设备中断向量) 200—217 80—85 BASIC使用 218—3C3 86—F0 BASIC运行时,用于解释 3C4—3FF F1—FF 未用 表9.2 DOS中断类型
9.1 键盘输入中断调用 9.1.1 ASCII与扫描码 9.1.2 BIOS键盘中断 9.1.3 DOS中断调用
9.1.1 ASCII与扫描码 键盘是计算机最基本的一种输入设备,用来输入信息,以达到人机对话的目的。键盘主要由3种基本类型的键组成: (1)字符数字键: (2)扩展功能键:如Home、End、Backspace、Delete、Insert、PgUp、PgDown以及功能键F1~F10 (3)和其他键组合使用的控制键:如Alt,Ctrl,Shift等
键盘和主机通过5芯电缆相连,这5根线分别是电源线、地线、复位线以及键盘数据线和键盘时钟线。PC机系列的键盘触点电路按16行×8列的矩阵来排列,用单片机Intel8048来控制对键盘的扫描。按键的识别采用行列扫描法,即根据对行线和列线的扫描结果来确定闭合键的位置,这个位置值称为按键的扫描码,通过数据线将8位扫描码送往主机。当在键盘上“按下”或“放开”一个键时,如果键盘中断是允许的(21H端口的第一位等于0),就会产生一个类型9的中断,并转入到BIOS的键盘中断处理程序。键盘和主机通过5芯电缆相连,这5根线分别是电源线、地线、复位线以及键盘数据线和键盘时钟线。PC机系列的键盘触点电路按16行×8列的矩阵来排列,用单片机Intel8048来控制对键盘的扫描。按键的识别采用行列扫描法,即根据对行线和列线的扫描结果来确定闭合键的位置,这个位置值称为按键的扫描码,通过数据线将8位扫描码送往主机。当在键盘上“按下”或“放开”一个键时,如果键盘中断是允许的(21H端口的第一位等于0),就会产生一个类型9的中断,并转入到BIOS的键盘中断处理程序。
该处理程序从8255可编程外围接口芯片的输入端口读取一个字节,这个字节的低7位是按键的扫描码。最高位为0或者为1,分别表示键是“按下”状态还是“放开”状态。按下时,取得的字节称为通码,放开时取得的字节称为断码。如ESC键按下取得的通码为01H(00000001B),放开ESC键时会产生一个断码81H(10000001B)。该处理程序从8255可编程外围接口芯片的输入端口读取一个字节,这个字节的低7位是按键的扫描码。最高位为0或者为1,分别表示键是“按下”状态还是“放开”状态。按下时,取得的字节称为通码,放开时取得的字节称为断码。如ESC键按下取得的通码为01H(00000001B),放开ESC键时会产生一个断码81H(10000001B)。 BIOS键盘处理程序将取得的扫描码转换成相应的字符码,大部分的字符码是一个标准的ASCII码;没有相应ASCII的键,如Alt和功能键(F1~F10),字符码为0;还有一些非ASCII码键产生一个指定的操作。
键盘缓冲区 键盘缓冲区是一个先进先出的环形队列,其所占内存区域如下: KBHead DW? ;其内存地址为0000:041AH,缓冲区头指针 KBTail DW? ;其内存地址为0000:041CH,缓冲区尾指针 KBBuff DW16 DUP(?) ;其内存地址为0000:041EH,该缓冲区 的缺省长度为16个字 键盘缓冲区是一个环形队列,其性质与《数据结构》课程中对“环形队列”所描述的性质完全一致。虽然缓冲区的本身长度为16个字,但出于判断“对列满”的考虑,它最多只能保存15个键盘信息。当缓冲区满时,系统将不再接受按键信息,而会发出“嘟”的声音,以示要暂缓按键。当KBHead=KBTail时,表示无键盘输入。
9.1.2 BIOS键盘中断 类型 16H 的中断提供了基本的键盘操作,它的中断处理程序包括3个不同的功能,分别根据AH寄存器中的子功能号来确定。 (1)AH=0 本功能为从键盘读字符到AL寄存器中。(AL=字符码,AH=扫描码) (2)AH=1 本功能为读键盘缓冲区字符到AL寄存器中, 并置ZF标志位。(若ZF=0,则AL=字符码,AH=扫描码, ZF=1,缓冲区空) (3)AH=2 本功能为读取特殊功能键的状态。(AL=键盘状态字节)
从键盘读字符 code segment assume cs:code mov ah, 0 int 16h mov ah, 4ch int 21h code ends end
键盘状态字 在计算机键盘上除了可输入各种字符(字母、数字和符号等)的按键之外,还有一些功能键(如:F1、F2、…等)、控制键(如:Ctrl、Alt、Shift等)、双态键(如:Num Lock、Caps Lock等)和特殊请求键(如:Print Screen、Scroll Lock等)。 键盘中的控制键和双态键是非打印按键,它们是起控制或转换作用的。当使用者按下控制键或双态键时,系统要记住其所按下的按键。为此,在计算机系统中,特意安排的一个字来标志这些按键的状态,我们称该字为键盘状态字。 键盘状态字的各位含义如图所示。
读取特殊功能键的状态 code segment assume cs:code mov ah, 2 int 16h mov ah, 4ch int 21h code ends end
1)单字符输入 例9—2 接收键盘输入并对其进行测试。 get_key:mov ah, 1 int 21h cmp al , ’y’ je yes cmp al, ’n’ je no jne get_key
例9—3 检测键盘输入的字符是否是回车键。 wait_here: mov ah, 7 int 21h cmp al, 0dh jne wait_here
code segment assume cs:code mov ah,7 int 21h cmp al,0 je get_char jmp error get_char_ mov ah,7 int 21h cmp al,3bh ;F1 je option1 cmp al,3ch ;F2 je option2 mov ah,4ch int 21h code ends end 如果程序要求能接收功能键或数字组合键必须进行两次DOS功能调用: 第一次回送00 第二次回送扫描码 例9-4 检测键盘输入的功能键。
2)输入字符串 例9-5 输入字符串程序 data segment smax db 21 sact db ? stri db 21 dup(?) data ends code segment assume cs:code,ds:data Start:mov ax,data mov ds,ax lea dx, stri mov ah,0ah int 21h mov ah,4ch int 21h code ends End start (1) smax db 21 sact db ? stri db 21 dup(?) (2) smax db 21 db ? db 21 dup(?) (3)smax db 21, ?, 21 dup(?)
3)清除键盘缓冲区 Int 21的功能0ch能清除键盘缓冲区,然后执行在AL中指定的功能。AL中指定的功能可以是1,6,7,8或0AH。 … mov ah, 0ch mov al, 08h int 21h inc al je exit … Exit:
4)检验键盘状态 例 编写按任意键结束程序的程序段 … mov ah, 0bh int 21h inc al je exit … Exit:
9.2 显示器I/O 显示器可以简单的分为单色显示器和彩色显示器。随着显示技术的发展,种类也更加丰富,常见的有阴极摄像管(CRT)、液晶显示器、等离子显示器等。 显示器是通过显卡与主机相连。显示器的显示屏通常称之为屏幕,现在常用的显示器有14"和17",常用的显示分辨率为800×600或1024×768等。常用的显示卡类型为VGA、SVGA、EVGA和TVGA等,显示卡上也都带有大量的显示存储器,能快速显示精美的图象。 1.MDA MDA(Monochrome Display Adapter )属于单色显示适配器,是IBM最早研制的视频显示适配器。 2.CGA 在MDA推出的同时,IBM也推出了彩色图形显示适配器──CGA(Color Graphics Adapter)。
3.EGA 增强图形显示适配器──EGA(Enhanced Graphics Adapter)是IBM公司推出的第二代图形显示适配器,它兼容了MDA和CGA的全部功能。 4.VGA 视频图形阵列显示适配器──VGA(Video Graphics Array)是IBM公司推出的第三代图形显示适配器,它兼容了MDA、CGA和EGA的全部功能。 5. XGA XGA(Extended Graphics Array)是IBM公司继VGA之后推出的扩展图形显示适配器。
显示模式 计算机系统中的显示器都有二种显示方式:文本显示方式和图形显示方式。 在DOS操作系统环境下,其默认的显示方式为文本显示方式,而在Windows操作系统环境下,其显示方式是图形显示方式,其绝大多数操作界面是以图形界面的窗口形式出现的。
文本显示方式 文本显示方式是指以字符为最小单位的显示方式,每个字符都是以矩形块形式显示的。在BIOS ROM中存有多种不同大小的字符集,主要的显示字符集大小为:8×8(标准)、8×14和8×16等。 在常用的文本显示模式(模式3)下,屏幕被划分成25行,每行可显示80个字符,所以,每屏最多可显示2000(80×25)个字符。为了便于标识屏幕上的每个显示位置,我们就用其所在行和列来表示之,并规定:屏幕的左上角坐标为(0, 0),右下角坐标为(24, 79)。 在显示字符时,用一个字节存储该字符的ASCII码,用另一个字节存储的显示属性,即:显示颜色。 在80×25的文本显示模式下,满屏可显示2000个字符,也就需要4000个字节来存储一屏的显示信息。
图形显示方式 图形显示是目前最常用的一种显示方式,也是Windows操作系统的默认显示方式。在该显示方式下,我们可以看到优美的图象、VCD、浏览丰富多彩的网页等。 图形显示的最小单位是象素,对每个象素可用不同的颜色来显示。所以,在显示缓冲区内记录的信息是屏幕各象素的显示颜色。 由于各种图形显示模式所能显示的颜色和象素是不同的,它决定了显示缓冲区的存储方式也是不同的。下面给出三个具体的图形显示模式及其存储方式,通过它们可看出各种显示模式在显示缓冲区存储方式上的明显差异。
4色320×200图形显示模式 由于每个象素只能是四种颜色之一,而四种情况用2位二进制就可表示,所以,一个字节可表示4个象素的显示颜色,存储一行上的所有象素信息就需要80个字节。 在具体存储过程中,它又把偶数行象素和奇数行分开来存储。偶数行和齐数行的象素总数各有32000个,也都需要8000个字节来存储,并规定: 偶数行象素从0B800:0000H开始存储, 奇数行象素从0B800:2000H开始存储。 该显示模式的存储形式如图所示。
16色640×480图形显示模式 640×480图形显示模式共有307200个象素,每个象素可选用16种颜色,它需要用4位二进制来表示。该显示模式在存储显示信息时,把该4位分在四个位平面P1、P2、P3和P4上,所以,位平面Pi(i=1,2,3,4)共有307200个二进制位,即有38400个字节。其显示缓冲区的存储形式如图所示。
256色320×200图形显示模式 表达256种不同颜色需要8位二进制,即一个字节。在该模式下,其显示缓冲区的存储方式是非常简单的,即:第一个字节存储第一个象素的颜色,第二个字节存储第二个象素的颜色,以此类推,所以,存储满屏象素所需要的字节数为:320×200×1=64000。其显示缓冲区的存储方式如图所示。
从上面三种不同图形显示模式的介绍,不难看出:各种显示模式在显示缓冲区存储方式上的明显差异,操作象素方法的难易程度相差也很大,所以,再次建议:程序员不要用直接操作显示缓冲区的办法来达到改变显示象素的目的,最好是通过BIOS内的中断功能来实现相应的功能,这样,所编写的程序能很方便地适应不同的图形显示模式。从上面三种不同图形显示模式的介绍,不难看出:各种显示模式在显示缓冲区存储方式上的明显差异,操作象素方法的难易程度相差也很大,所以,再次建议:程序员不要用直接操作显示缓冲区的办法来达到改变显示象素的目的,最好是通过BIOS内的中断功能来实现相应的功能,这样,所编写的程序能很方便地适应不同的图形显示模式。
9.2.1 字符属性 显示器的屏幕通常划分为行和列的二维系统,显示适配器就在行列组成的网格位置上显示字符。对应屏幕上的每个字符位置,主存空间都有相应的存储单元与之对应,因此可说是显示屏幕式“存储器的映像”。对应显示屏幕上的每个字符,在存储器中由连续的两个字节表示,一个字节表示ASCII码,另一个字节保存字符的属性。
1、单色字符属性 7 6 5 4 3 2 1 0 前景 闪烁 背景 亮度 单色显示的属性值
位号 7 6 5 4 3 2 1 0 属性 字节 BL R G B I R G B 闪烁选择 背景颜色 前景颜色 2、彩色字符显示 彩色字符显示属性字节
RGB IRGB 颜色 颜色 IRGB 颜色 000 0000 黑 黑 1000 灰 001 0001 蓝 蓝 1001 浅蓝 010 0010 绿 绿 1010 浅绿 0011 011 青 青 1011 浅青 0100 100 红 红 1100 浅红 0101 101 品红 品红 1101 浅品红 0110 110 棕 棕 1110 黄 111 0111 白 白 1111 强度白 背景颜色组合 前景颜色组合
3. 显示存储器 对于所有的显示适配器,文本方式下显示字符的原理是一样的,所不同的是显存的起始地址不同,对于MDA,显存的起始地址为B000:0000;对于CGA、EGA、VGA是B800:0000.每个字符的ASCII码和属性码字节存放于两个连续的字节中。图形显示方式下,其显示缓冲区段地址为0A000H。 在25 X 80的文本显示方式下,屏幕可有2000个字符位置,因每个字符需要用两个字节,显存容量需要多少?如果显存有16K,可保存几屏幕的数据?对CGA,EGA和VGA的80列显示方式,0页的起始地址是B800:0000,1页的起始地址是B800:1000,2页的起始地址为B800:2000,3页的起始地址为B800:3000 。 如何计算一个字符在显存中的位置?
9.2.2 BIOS显示中断调用 10H中断调用为显示器中断,共有17种功 能。下面列出几种主要功能的使用情况。 (1)设置显示方式(0号功能) 入口参数:AH=0(功能号),AL=设置方式(0~7)。 出口参数:无。 (2)设置光标类型(1号功能) 入口参数:AH=1(功能号),CH=光标开始行,CL=光标结束行。 出口参数:无。根据CX给出光标的大小。
AL 显示方式 0 40×25黑白文本方式 1 40×25彩色文本方式 2 80×25黑白文本方式 3 80×25彩色文本方式 4 320×200彩色图形方式 5 320×200黑白图形方式 6 640×200黑白图形方式 7 80×25黑白文本方式(单色显示卡)
(3)设置光标位置(2号功能) 入口参数:AH=2(功能号),BH=页号,DH=行号,DL=列号。 出口参数:无。根据DX确定了光标位置。 (4)读当前光标位置(3号功能) 入口参数;AH=3(功能号),BH=页号。 出口参数:DH=行号,DL=列号,CX=光标大小。 (5)初始窗口或向上滚动(6号功能) 入口参数:AH=6,AL=上滚行数,CX=上滚窗口左上角的行、列号。DX=上滚窗口右下角的行、列号。BH=空白行的属性。 出口参数:无。当滚动后,底部为空白输入行。
(6)初始窗口或向下滚动(7号功能) 入口参数:AH=7,AL=下滚行数,CX=下滚窗口左上角的行、列号。DX=下滚窗口右下角的行、列号。BH=空白行的属性。 出口参数:无。当滚动后,顶部为空白输入行。 (7)读当前光标位置的字符与属性(8号功能) 入口参数:AH=08H,BH=页号。 出口参数:AL为读出的字符,AH为字符属性。
(8)在当前光标位置写字符和属性(9号功能)(8)在当前光标位置写字符和属性(9号功能) 入口参数:AH=9,BH=页号,AL=字符的ASCII码,BL=字符属性,CX=写入字符重复次数。 出口参数:无。 (9)在当前光标位置写字符(10号功能) 入口参数:AH=0AH,BH=页号,AL=字符的ASCII码,CX=写入字符重复次数。 出口参数:无。
(10)显示字符串(13号功能) ES:BP=串地址 CX=串长度 DH,DL=起始行列 BH=页号 AL=0,BL=属性 串:char,char…char 光标返回到起始位置 AL=1,BL=属性 串:char,char…char 光标跟随串移动 AL=2 串:char,char…char 光标返回起始位置 AL=3 串:char,char…char 光标跟随串移动
例 置光标开始行为5,结束行为7,并把它设置到第五行第六列 code segment assume cs:code start: mov ch,5 mov cl,7 mov ah,1 int 10h mov dh,5 mov dl,6 mov bh,0 mov ah,2 int 10h mov ah,4ch int 21h code ends end start 设置光标类型(1号功能) 入口参数:AH=1(功能号),CH=光标开始行,CL=光标结束行。 出口参数:无。根据CX给出光标的大小。 设置光标位置(2号功能) 入口参数:AH=2(功能号),BH=页号,DH=行号,DL=列号。 出口参数:无。根据DX确定了光标位置。
例:编写清除全屏幕的程序 clear segment assume cs:clear mov ah,6 mov al,0 mov bh,7 mov ch,0 mov cl,0 mov dh,24 mov dl,79 int 10h mov dx,2 mov ah,2 int 10h mov ah,4ch int 21h clear ends end 初始窗口或向上滚动(6号功能) 入口参数:AH=6,AL=上滚行数,CX=上滚窗口左上角的行、列号。DX=上滚窗口右下角的行、列号。BH=空白行的属性。 出口参数:无。当滚动后,底部为空白输入行。 设置光标位置(2号功能) 入口参数:AH=2(功能号),BH=页号,DH=行号,DL=列号。 出口参数:无。根据DX确定了光标位置。
例 清除左上角为(00)右下角为(24,39)的窗口,初始化为反相显示。该窗口相当于屏幕的左上角 clear segment assume cs:clear mov ah,7 mov al,0 mov bh,70h mov ch,0 mov cl,0 mov dh,24 mov dl,39 int 10h mov dx,2 mov ah,2 int 10h mov ah,4ch int 21h clear ends end 初始窗口或向下滚动(7号功能) 入口参数:AH=7,AL=下滚行数,CX=下滚窗口左上角的行、列号。DX=下滚窗口右下角的行、列号。BH=空白行的属性。 出口参数:无。当滚动后,顶部为空白输入行。 设置光标位置(2号功能) 入口参数:AH=2(功能号),BH=页号,DH=行号,DL=列号。 出口参数:无。根据DX确定了光标位置。
例 在屏幕中心显示小窗口 cmp al, esc_key jz exit loop get_char mov ah,6 mov al,1 mov ch,win_ulr mov cl,win_ulc mov dh,win_lrr mov dl,win_lrc mov bh,7 int 10h jmp start exit:mov ah,4ch int 21h code ends end data segment esc_key equ 1bh win_ulc equ 30 win_ulr equ 8 win_lrc equ 50 win_lrr equ 16 win_width equ 20 data ends code segment assume cs:code,ds:data start:mov ah,2 mov dh,win_lrr mov dl,win_ulc mov bh,0 int 10h mov cx,win_width get_char: mov ah,1 int 21h 初始窗口或向上滚动(6号功能) 入口参数:AH=6,AL=上滚行数,CX=上滚窗口左上角的行、列号。DX=上滚窗口右下角的行、列号。BH=空白行的属性。 出口参数:无。当滚动后,底部为空白输入行。 设置光标位置(2号功能) 入口参数:AH=2(功能号),BH=页号,DH=行号,DL=列号。 出口参数:无。根据DX确定了光标位置。