第3章 BIOS和DOS系统功能调用 3.1 系统资源的软接口 汇编语言比较适合于编制直接管理计算机硬件设备的底层软件。在进行计算机系统的应用开发过程中,常常需要利用计算机的系统资源,包括系统本身配置的硬件设备和软件程序,但实际上用户最常使用的系统资源是系统软件中的一些中断程序,这些子程序提供了非常丰富的功能,如对键盘、显示器、打印机、串行通信等设备的输入/输出服务,对内存的管理,对文件和作业的管理以及时钟、日历的读出和设置等一系列的功能。操作系统和用户的应用程序都可以使用这些系统软件资源。 ROM-BIOS以BIOS调用的方式向用户提供了一个系统与用户之间的接口界面,也称为软接口,使用户在进行应用程序设计时可以采用BIOS调用的方式来使用系统资源。 PC-DOS提供了大量的中断服务程序,其中,类型码为21H的中断服务程序包含了一百多号功能模块,可以提供给系统软件和应用程序调用,也称系统功能调用,它们也是用户程序与系统资源的一个软接口界面。 DOS系统将各种功能子程序顺序编号,称为功能号,用户需要使用系统资源时,只需要在用户程序中使用“INT 21H”指令,调用相应的功能号。 系统提供的ROM-BIOS接口和PC-DOS接口都是系统资源的软接口,它们为用户提供了一系列例行子程序,用户不必过问其内部结构和细节,也不必关心硬件I/O接口的特性,只要用一条软件中断指令“INT n”就可以调用,称为中断调用。 用户程序使用系统资源的方法主要有两种: 一种方法是使用“INT 21H”指令进行DOS系统功能调用,另一种方法是进行BIOS调用来使用ROM-BIOS中的I/O中断服务程序。 总之,BIOS和DOS系统功能都是通过内部中断调用,调用方法非常方便、简单,只需要按规定的步骤就可以完成BIOS或DOS功能调用: (1) 设置入口参数。 (2) 设置系统功能号。 (3) 执行中断指令“INT n" ,进行中断调用。 3.2 BIOS和DOS系统功能调用方法 系统功能调用是程序设计的一个重要方面,DOS利用类型码21H号中断提供给用户近百个系统功能,也就是近百个独立的中断服务程序。而驻留在ROM中的BIOS基本输入/输出系统为用户提供了更基本的不依赖于操作系统的功能调用。这些系统功能调用为用户程序和系统程序提供了主要外设的控制功能,计算机系统软件就是利用这些基本的设备驱动程序,实现各种功能操作。这些中断子程序的入口地址已由系统置入中断向量表中,在汇编语言程序中可以用中断指令直接调用,程序员不必深入了解有关设备的接口电路,只需要遵循DOS或BIOS规定的调用方法就可以直接调用了。 某些系统功能调用既能选用DOS中断,也能选用BIOS中断实现同样的功能。DOS系统功能调用对硬件的依赖性很少,建议读者尽可能使用DOS功能。 BIOS和DOS系统功能都是通过内部中断调用,调用方法非常方便、简单,只需要按以下步骤进行就可以完成BIOS或DOS功能调用: (1) 设置入口参数: 将入口参数送到指定的寄存器中。 (2) 将系统功能号送入AH寄存器中。 (3) 按中断类型码n调用BIOS或DOS中断,即执行中断指令“INT n" ,完成中断调用。 (4) 检查出口参数,分析调用结果是否正确。 有的子程序不需要入口参数,但大部分需要将入口参数送入指定的位置或指定的寄存器中。系统将中断类型码21H分配给DOS,程序员只须给出以上3个方面的信息,执行“INT 21H”指令,DOS就会自动转入相应的中断服务子程序去执行。而系统分配给BIOS的中断类型码n主要有10H、13H、16H、17H等,通过执行中断指令“INT n”可以直接调用。出口参数就是该子程序执行完以后的结果,一般存放在指定的寄存器中,有些子程序调用结束时会在屏幕上看到结果。 3.3 常用的DOS功能调用 1. 00H号调用: 终止程序,返回DOS 功能: (1) 完成终止当前程序执行,返回到操作系统状态。 (2) 同时将关闭所有文件并刷新所有文件缓冲区。 (3) 完成与“INT 20H”相同的操作。 调用方式: MOV AH,00H ;调用号装AH寄存器 INT 21H 2. 01H号调用: 读取键盘字符并回显 功能: (1) 首先扫描键盘,等待按键。 (2) 若有键按下,则检查所按键码。 (3) 当按Ctrl+Break键时,则退出执行。 (4) 当按其他键时,则将对应键的ACSII码送AL寄存器,同时回送在显示器上。 调用方式: MOV AH,01H ;调用号装AH寄存器 INT 21H3. 02H号调用、显示字符 功能: (1) 在显示器当前光标的位置输出显示一个字符。 (2) 当DL中存放退格符BS (08H) 、响铃符BEL (07H) 、回车符CR (0DH) 、换行符LF (0AH) ,该功能调用能进行相应的处理。如果按的是Ctrl+Break键,则退出执行。 调用方式: MOV AH,02H ;调用号装AH寄存器 MOV DL,'A';要显示输出的字符的ACSII码装DL寄存器 INT 21H 4. 03H号调用: 异步通信口输入 功能: (1) 完成从标准异步通信口(COM1)等待输入一个字符。 (2) 将输入的字符送寄存器AL中。 (3) DOS将异步通信口COM1初始化为2400波特,无校验位,有一个停止位和8个数据位。 (4) 执行后,AL中得到输入字符的ACSII码(出口参数). 调用方式: MOV AH,03H INT 21H5. 04H号调用: 异步通信口输出 功能: (1) 完成从标准异步通信口(COM1)等待输出一个字符。 (2) 入口参数是将要输出的字符的ACSII码。 (3) 异步通信口的输入/输出操作,建议使用ROM BIOS的14H号调用。 调用方式: MOV AH,04H INT 21H6. 05H调用: 打印输出 功能: (1) 打印的字符的ASCII码送入DL寄存器中。 (2) 向标准打印设备(PRN或LPT1)打印输出一个字符。 调用方式: MOV DL,'A' ;入口参数是要打印的字符A MOV AH,05H INT 21H7. 06H号调用: 直接控制台I/O 功能: (1) 从标准输入设备(键盘)输入字符,或向标准输出设备(显示器)输出字符。 (2) 当DL=FFH时,表示从键盘输入字符。 若标志位ZF=0,表示输入字符的ASCII码已读入AL中。 若标志位ZF=1,表示无键按下,AL中不是输入的字符值。 (3) 当DL≠FFH时,表示向显示器输出,DL中应存放输出字符的ASCII码。 (4) 该功能调用不检查Ctrl+Break键,这是它与01H号、02H号调用的区别。 调用方式: MOV DL,OFFH MOV AH,06H INT 21H 表示从键盘输入字符,当有键按下时,AL中就是输入字符的ASCII码。 MOV DL,41H MOV AH,06H INT 21H 表示将DL中41H所对应的字符A在屏幕上显示。 8. 07H号调用: 键盘输入无回显 功能: (1) 从标准输入设备(键盘)输入字符送AL寄存器中。 (2) 不回显字符,不检查输入的字符代码是否为Ctrl+Break. 调用方式: MOV AH,07H INT 21H9. 08H号调用: 键盘输入且不回显 功能: (1) 从标准输入设备(键盘)输入字符送AL. (2) 不回显字符,但对输入字符要作Ctrl+Break检查和处理。 调用方式: MOV AH,08H INT 21H10. 09H号调用: 字符串输出显示 功能: (1) 在标准输出设备(显示器)上输出显示一字符串 (2) 字符串必须存放内存中并以字符“$" (24H)为结束标志,但“$”字符不显示。 (3) 要求DS: DX作为该字符串的首地址。 (4) 显示字符后作Ctrl+Break检查和处理。 调用方式: MOV BX,SEG STRING ; MOV DS,BX ;DS←输出字符串的段地址 LEA DX,STRING;DX←输出字符串偏移地址 MOV AH,09H;09H号功能调用 INT 21H ;将内存中的字符串输出显示11. 0AH号调用: 键盘输入到缓冲区 功能: (1) 使DS: DX指向输入缓冲区首地址。 (2) 将从键盘接收的字符串存到指定内存的输入缓冲区,直到输入是回车符为止。 (3) 缓冲区第一个字节是指定缓冲区能接收字符的个数(1~255) ,缓冲区的第二个字节保留用作填入实际输入字符的个数,缓冲区的第三个字节开始存放从键盘上输入的字符,输入的最后一个字符是回车符。 (4) 若实际输入的字符数少于定义的字节数,则缓冲区内其余字节补零。若实际输入多于定义的字节数,则丢弃多余字符,响铃。 调用方式: MOV BX,SEG BUF ; MOV DS,BX ;DS←输入缓冲区段地址 LEA DX,BUF;DX←输入缓冲区偏移地址 MOV AH,0AH;0A号功能调用 INT 21H;从键盘输入字符串存到指定内存的输入缓冲区中12. 25H号调用: 设置中断向量 功能: 设置中断向量。将中断向量表中的内容设置为新的中断子程序的入口地址。 入口参数:DS:DX指向要插入到表中的中断子程序的地址;AL=中断类型码。 调用方式: MOV BX,SEG INTHAND ; MOV DS,BX ;DS←中断子程序的段地址 LEA DX,INTHAND;DX←中断子程序的偏移地址 MOV AH,25H;25H号功能调用 MOV AL,n;中断类型码n INT 21H;13. 35H号调用: 获取指定中断号的中断向量 功能: 获取指定中断号的中断向量。 入口参数: AL=中断类型码。 出口参数: ES=中断子程序的段地址, BX=中断子程序的偏移地址。 调用方式: LEA SI,OLDVECTOR MOV AH,35H ;35H号功能调用 MOV AL,n;中断类型码n INT 21H;中断向量在ES:BX中 MOV WORD PTR \,BX MOV WORD PTR \2\],ES 14. 2BH号调用: 设置日期 功能: 设置系统日期。 入口参数: CX: DH: DL=年: 月: 日。 出口参数: AL=00H,成功;AL=FFH,无效。 调用方式: MOV CX,1992 MOV DH,3 MOV DL,29 MOV AH,2BH INT 21H将计算机系统日期设置为1992年3月29日。 15. 2AH号调用: 取日期 功能: 取系统日期。 入口参数: 无。 出口参数: CX=年,DH: DL=月: 日。 调用方式: MOV AH,2AH INT 21H在(CX)中取得年号,在DX中的高8位取得月份,低8位中得到日(二进制). 16. 2D号调用: 设置时间 功能: 设置系统时间。 入口参数: CH=小时(0~23) , CL=分(0~59) , DH=秒(0~59) , DL=百分之一秒(0~99). 出口参数: AL=00H,成功;AL=FFH,无效。 调用方式: MOV CH,8 MOV CL,20 MOV DH,3 MOV DL,29 MOV AH,2DH INT 21H将系统时间设置为8点20分3秒。 3.4 常用的BIOS功能调用1. 视频功能: INT 10H 与DOS功能调用相比,BIOS功能调用是系统提供的基本输入/输出程序,可以不受任何操作系统的约束,利用BIOS功能编写的程序简洁、可读性好,而且易于移植。有些功能也只有BIOS才具有,如显示功能。 在显示彩色文本时,用属性字节可以选择前景(显示的字符)和背景的颜色: 其中,4~7位表示背景,0~3位表示前景(显示的字符), BL=1表示背景闪烁,否则不闪;I=1表示前景为高亮度,否则为一般亮度。R、G、B分别表示红、绿、蓝,当多个颜色位同时为1时,显示的是这几种颜色的配色。当R、G、B都为1时显示白色,R、G、B都为0时显示黑色。显示屏幕的背景颜色只能是I为0时的8种颜色,而每个字符的颜色可以有16种选择。如果前景和背景是同一种颜色,则显示出的字符是看不见的,但属性字节中的位7可以使字符闪烁(BL=1) 。有关0~3位控制字符颜色的编码如表3.1所示。表3.1 文本方式(图形方式)的16种颜色编码颜色编码颜色编码颜色编码颜色0000黑0100红 1000灰 1100浅红 0001蓝0101品红1001浅蓝1101浅品红0010绿0110棕 1010浅绿1110黄 0011青0111白 1011浅青1111亮白 BIOS视频服务的中断类型码为10H,其中断子程序完成显示操作,常用的部分显示功能如表3.2所示。表3.2 BIOS的中断类型10H的视频服务AH功 能调 用 参 数返 回 参 数0设置文本或图形显示模式AL=视频模式1置光标类型 (CH) 0~3=光标开始行 (CL) 0~3=光标结束行2置光标位置BH=页号 ; DH/DL=行/列3读光标位置BH=页号CH=光标开始行 CL=光标结束行 DH/DL=行/列4置显示页AL=显示页号5屏幕初始化或上卷6屏幕初始化或上卷AL=上卷行数 AL=0全屏幕为空白 BH=卷入行属性 CH/CL=左上角行号/列号 DH/DL=右下角行号/列号 7 屏幕初始化或下卷AL=下卷行数 AL=0全屏幕为空白 BH=卷入行属性 CH/CL=左上角行号/ 列号 DH/DL=右下角行号/列号 续表AH功 能调 用 参 数返 回 参 数8读光标位置的属性和字符BH=显示页AH/AL=属性/字符9在光标位置显示字符及其属性BH/BL=显示页/属性 AL=字符 CX=字符重复次数A在光标位置只显示字符BH=显示页 AL=字符 CX=字符重复次数E 显示字符(光标前移)AL=字符 BL=前景色光标跟随字符移动13显示字符串ES:BP=串地址 AL=写方式(0~3) CX=串长度 DH/DL=起始行/列 BH/BL=页号/属性 AL=0, BL=字符串属性 串:Char, …, char AL=1, BL=字符串属性 串:Char, …, char AL=2 串:Char, attr, …, char, attrAL=3 串:Char, attr, …, char, attr光标返回起始位置 光标跟随移动 光标返回起始位置 光标跟随串移动 INT 10H的功能0: 设置文本或图形的显示模式、入口参数: AL=视频模式,模式的编号的意义如表3.3所示。表3.3 不同视频模式的意义AL=视频模式分辨率颜色数量AL=视频模式分辨率颜色数量040×251380×2516140×2516780×252280×25214H132×2516 调用举例: 设置彩色文本显示模式。 MOV AH,0 ;功能号 MOV AL,3;视频模式 INT 10HINT 10H的功能1: 使光标显现或关闭。这个功能也控制光标行的开始和结束,也就是说控制光标的大小。表示光标行开始和结束的数据分别放在CH和CL的低4位(0~3) , 当CH的低4位为1时,光标不显现出来(关闭);当低4位为0时,光标在屏幕上显现出来。单色显示器的光标大小的范围为0~13. 调用举例: 设置光标开始行为6,结束行为7. MOV AH,1 MOV CX,0607H INT 10HINT 10H的功能2: 设置光标位置。光标位置的行号设在DH寄存器中,列号设在DL中。在24×80的显示方式中,坐标设在(0, 0)是屏幕的左上角, (24, 79)是屏幕的右下角。BH中必须包含被输出的页号,对单色显示器来说,页号总是0. 调用举例: 把光标设置到当前页的第10行、第20列。 MOV AH,2 MOV DH,10 MOV DL,20 MOV BH,0 INT 10HINT 10H的功能3: 读光标位置,页号必须在BH中指定。此功能把光标位置的行号回送给DH,列号回送给DL。光标大小的参数填入CH和CL,也就是说,在CH和CL中回送的是用功能1设置的光标参数。 调用举例: 读0页当前光标的位置。 MOV AH,3 MOV BH,0 INT 10HINT 10H的功能6: 能使屏幕内容上卷指定的行,这个功能需要设置7个参数,其属性由BH寄存器决定。如果AL=0,则完成清除屏幕的功能。 调用举例: 清除全屏幕。 MOV AH,6 MOV AL,0 MOV CH,0 MOV CL,0 MOV DH,24 MOV DL,79 MOV BH,7 INT 10HINT 10H的功能7: 与功能6类似,能使屏幕(或窗口)初始化或使屏幕(或窗口)的内容下卷指定的行,其他参数的设置与功能6一样。 调用举例: 清除左上角为(0, 0) 、右下角为(24, 39)的窗口,并反向显示。 MOV AH,7 MOV AL,0 MOV CH,0 MOV CL,0 MOV DH,24 MOV DL,39 MOV BH,70H INT 10HINT 10H的功能8: 可读取当前光标位置的字符及属性。如果用户需要设计一个能直接从屏幕读取文本的程序,则可以使用该功能。 调用举例: 读取当前光标位置的字符及属性。 MOV AH,8 ;功能号 MOV BH,0;当前页 INT 10H;返回值: AL=字符的ASCII码,AH=字符的属性 MOV CHAR,AL MOV ATTR,AHINT 10H的功能9: 能把一个字符送到屏幕显示,然后光标返回到它的初始位置,所以在当前光标位置上写一个字符之后,必须用INT 10H的02H号功能移动光标到下一个字符位置上。 调用举例: 显示字符并设置其属性。 MOV AH,9 MOV AL,'A' ;字符的ASCII码 MOV BH,0;当前页 MOV BL,71H;以白底蓝字显示 MOV CX,1;重复次数 INT 10HINT 10H的功能0A: 与功能9类似,它与功能0A的区别是,AH=9的功能把字符及其属性输出到当前光标位置上,而AH=0AH的功能只输出字符,它的属性值就是这一位置上先前已具有的属性。0AH功能在使用单色显示器时特别方便,因为这时人们很少改变显示字符的属性。 调用举例: 在光标位置只显示字符。 MOV AH,0AH MOV AL,'A' MOV BH,0 MOV CX,1 INT 10H 2. 键盘功能: INT 16H BIOS的键盘功能调用(INT 16H)比DOS的键盘功能调用(INT 21H)多一些功能。以下是一些常用的键盘功能的介绍。 INT 16H的功能0: 从键盘输入一个字符,返回参数: AL=字符码,AH=扫描码。 调用举例: 查看按键的扫描码和字符的ASCII码。 MOV AH,0 INT 16H