您的位置: 网站首页 > 程序开发 > 汇编语言与微机原理教程 > 第10章 宏汇编语言 > 【10.4 BIOS和DOS功能调用】

10.4 BIOS和DOS功能调用

 

10.4  BIOSDOS功能调用

10.4.1  BIOS功能调用

BIOS功能(子程序)调用通过软中断指令INT实现,其格式为:INT    n

n的取值范围是0255,每个n对应一段子程序。与一般子程序调用一样,在BIOS功能调用前也要设入口参数,功能调用也会返回参数(不是所有的功能都有参数返回)。本节将介绍几个最常用的BIOS调用。

1INT 16H键盘输入。

AH=0:从键盘读入一键。

返回参数:AL=ASCII码,AH=扫描码。

功能:从键盘读入一个键后返回,按键不显示在屏幕上。对于无相应ASCII码的键,如功能键等,AL返回0。此时,应再次以AH=0调用,AL中返回该键的扩展编码(大多数情况下与扫描码相同)。

AH=1:判断是否有键盘输入。

返回参数:若ZF=0,则有键盘输入,AL=ASCII码,AH=扫描码;若ZF=1,键盘无输入。

2INT 33H鼠标功能。

INT 33H用于提供鼠标的相关信息,如鼠标的当前位置、最近一次的按键和移动速度、鼠标的按下和释放状态等。

注意:INT 33H的功能号应该送AX而不是常用的AH

下面介绍几种最常用的鼠标功能。

AX=1:显示鼠标指针。

使鼠标指针显示在屏幕上,无返回参数。

AX=2:隐藏鼠标指针。

无返回参数,执行后鼠标指针不可见,但是鼠标的位置仍然被记录。

AX=3:获取鼠标位置和状态。

返回参数:BX=鼠标状态,其中D0=1表示左键被按下,D1=1表示右键被按下,D2=1表示中键被按下;CX=鼠标当前的X坐标(水平位置,以像素为单位);DX=鼠标当前的Y坐标(垂直位置,以像素为单位)。

MS-DOS下,一个字符的宽和高都是8个像素,因此像素的坐标除以8就转换成字符的坐标。

AX=4:设置鼠标的位置。

入口参数:CX=X坐标(水平位置,以像素为单位);DX=Y坐标(垂直位置,以像素为单位),无返回参数。

如果想把鼠标定位于第5行第6列字符处,设置CX=5×8=40DX=6×8=48。例如,跟踪鼠标,在屏幕的右上角显示鼠标的即时坐标。

INCLUDE    YLIB.H.MODEI    SMALI.CODE

MAIN PROC

CALL    SHOWMOUSE

AGAIN:

CALL    SETXY                   ; 设置光标位置(160列)

CALL    GETPOSITION             ; 获得鼠标的当前位置

CALL    SHOWPOSITIoN            ; 在光标处显示鼠标位置行:列

MOV     CX,2000H

LOOP    $                       ; 延时

JMP    AGAIN                     ; 重复上面过程,直到按下Ctrl+Break组合键

MAIN    ENDP

SHOWMOUSE PROC                  ; 子程序SHOWMOUSE,使鼠标指针可见

PUSH    AX

MOV     AX,1

INT     33H

POP     AX

RET

SHOWMOUSE  ENDP

SETXY    PROC

MOV  AH,2

MOV  DH,1

MOV  DI,60

MOV  BH,0   

INT  10H                        ; 设置光标位置为160

RET

SETXY    ENDP

GETPOSITION  PROC               ; 子程序GETPOSITION

MOV  AX,3

INT  33H                        ; 得到鼠标当前位置在CX/DX

RET

GETPOSITION  ENDP

SHOWPOSITION PROC               ; 子程序SHOWPOSITION

PUSH  CX

MOV   AX,DX

MOV   DX,0FFFFH

CALL  WRITEINT                  ; 显示鼠标当前的行号(垂直位置)

MOV   DI,''

MOV   AH,02H                    ; 输出一个冒号

INT   21H

POP   AX

MOV   DX, 0FFFFH

CALL  WRITEINT                  ; 显示鼠标当前的列号(水平位置)

RET

SHOWPOSITION    ENDP

END    MAIN

10.4.2  DOS功能调用

BIOS功能调用相比,DOS功能调用功能更强大,使用更方便。但是,DOS功能调用没有重入功能,也就是不能递归调用,所以不能在中断服务程序内使用。

MS-DOS负责文件管理、设备管理、内存管理和一些辅助功能,功能十分强大。DOS功能调用使用INT 21H指令,AH中存放功能号,表示需要完成的功能。每个功能调用都规定了使用的入口参数和存放该参数的寄存器,调用产生的返回参数也通过寄存器传递。

MS-DOS不仅为用户提供了许多可直接使用的命令,而且还为汇编语言的用户提供了几十个内部子程序,供程序员直接调用。为方便调用,每个子程序对应有一个调用功能号。

系统功能调用中的几十个子程序已成为汇编语言程序员的重要工具,程序员不必了解所使用设备的物理特性、接口方式和内存分配,不必编写复杂的控制程序,调用它们时采用统一的格式,只需要做到:

1)所需的入口参数送指定单元(通常是指定的寄存器)。

2)将子程序功能号送入AH寄存器中。

3)执行INT 21H指令,实现DOS功能调用。

DOS根据功能号携带入口参数转入相应的子程序执行,运行的结果由出口参数带出,一般也在某些寄存器中。

1)字符输入功能调用(1号)。它没有入口参数,执行1号系统功能调用时,系统等待键盘输入,当按下任何一个键时,系统先检查是否为Ctrl+Break组合键,如果是则退出运行的程序,否则将输入字符的ASCII码送入AL寄存器中,并在屏幕上显示该字符,程序继续向下执行。1号系统功能调用的格式如下:

MOV AH1

INT  21H

2)字符输出功能调用(2号)。2号调用的功能是将DI寄存器中的字符送屏幕上输出显示。2号调用时要求将显示字符的ASCII码(入口参数)事先送入DI中。

3)字符串输入功能调用(10号)。10号系统功能调用是将键盘上输入的字符串写到内存缓冲区中,因此要求事先在内存储器中定义一个输入缓冲区,缓冲区的第一个字节单元给出该缓冲器能容纳的字符个数,第二字节单元留给系统填入实际输入的字符个数,从第三字节单元开始用来存放输入的字符串。调用前,必须使DSDX指向该缓冲区。执行10号功能调用时,系统等待从键盘上输入字符,输入Enter键表示字符串输入结束。如果实际输入的字符数不足以填满缓冲区,则剩余的字节存储单元填0,如果实际输入的字符数超过定义的缓冲区容量,则超出的字符被丢弃,并且响铃警告。

4)字符串输出功能调用(9号)。9号系统功能调用是将指定的内存缓冲区中字符串输出到屏幕上显示或到打印机上打印。9号功能调用要求缓冲区首地址必须由DSDX给出,同时字符串必须以字符$结束。

例如,显示字符串“Hello!”,程序段编制如下:

BUF     DB'Hello!', '$'

MOV     DX, OFFSET BUF              ; 入口参数

MOV     AH, 09

INT     21H

执行上述的9号调用时,将在屏幕光标处输出整个字符串(不包括字符$)。

例如,利用DOS系统功能的9号和10号调用,可以实现人机对话。下面是一个简单的人机对话程序。

DATA    SEGMENT

PARS DB 20                      ; 定义缓冲区字节

DB  ?

DB 20 DUP(?)                    ; 10号调用的输入字符串存储缓冲区

MESG DB'What is your name?'     ; 要显示的提问信息

DB '$'

DATA    ENDS

STACK    SEGMENT PARA  STACK  'STACK'

DB  100 DUP(?)

TOP    LABEL  WORD

STACK ENDS

CODE    SEGMENT

ASSUME  CSCODE,DS:DATA,SS:STACK

START PROC FAR

BEGIN:PUSH DS

MOV AX,0

PUSH AX

MOV AX,DATA

MOV DS,AX

MOV AX,STACK

MOV SS,AX

MOV SP,TOP

DIAP:   MOV DX,OFFSET MESG

MOV AH, 09                      ; 9号调用显示提问信息

INT 21H

KEYBOD:MOV DX,OFFSET PARS

MOV AH,10

INT 21H                         ; 10号调用,等待从键盘上输入应答信息

RET                             ; 返回DOS操作系统

SART ENDP

CODES ENDS

EMD BEGIN

5)从异步通信口输入单个字符调用(3号)。3号系统功能调用从异步通信口串行输入一个字符并送入AL中,无入口参数。

6)向异步通信口输出单个字符(4号)调用。4号系统功能调用将DI中的字符向异步串行通信口输出,例如:

MOV     DI,'A'

MOV     AH,04H

INT     21H

7)返回DOS4CH 号)调用。4CH号功能调用使用的格式如下:

MOV     AH,4CH

INT     21H

执行4CH号功能调用的结果是结束当前正在执行的程序,返回DOS系统,无入口参数。

8)日期设置调用(2BH号)。2BH号功能调用是用来设置系统有效日期的。调用时寄存器CX中必须有一个有效年份(19802099),DH存放月份(0112),DL中存放日期(131)。例如需要设置的日期为2004918,则设置日期程序段如下:

MOV     CX,2004H

MOV     DX,0918H

MOV     AH,2BH

INT     21H

执行结果是将系统有效日期设置为2004918 日,如果设置成功,则AL0,否则ALFFH(即-1)。

9)读取日期调用(2AH号)。2AH号系统功能调用用于将系统当前日期读取到CXDX寄存器中,是2BH号调用的逆过程,无入口参数,其使用格式如下:

MOV AH,2AH

INT  21H

执行结果是将年号送入CX寄存器中,月份和日期送入DX寄存器中。

10)时间设置调用(2DH号)。2DH号系统功能调用设置系统时间,调用时要将入口参数有效时间送入CXDX寄存器,其中CH存放时(023),CL存放分(059),DH存放秒(059),DL存放百分秒(099)。如要使当前系统时间为162839.58秒,则其使用格式如下:

MOV CX,1628H        ;CX16:28

MOV DX,3958H        ;DX39"58

MOV AH,2DH

INT 21H

执行结果是将当前有效时间设置成162839.58秒。如果设置成功,则将AL寄存器清零,否则把FFH-1)送入AL寄存器。

11)读取时间调用(2CH号)。2CH系统功能调用是将当前的系统时间读入CXDX寄存器中,是2DH调用的逆过程,无入口参数,使用格式如下:

MOV AH,2CH

INT  21H

执行结果是将当前时间读入CXDX寄存器中,存放格式与设置时间格式相同。