DOS程序员手册(十)

终于到(十)了~~~

503页

                ES:DI       指向未更新且未打开的FCB的指针

    注释:该功能最初用来从命令行中析取文件,并以正确的格式来保存此文件

    以便打开FCB。为了实现这个目的,可首先将指针指向文件名字符串,并接着

    将另一个指针指向打算使用的FCB。没有必要采用任何种类的格式来保存

    FCB,单用内存块就能十分有效地保存好它。

        在所有版本中,分隔符无非就是如下几种:句号(.)、冒号(:)、分号(;),等

    号(=)、加号(+)、标记和空格。在DOS版本1中,还有以下几种符号也可用

    作分隔符:双引号(")、斜线(/)、左括号([)和右括号(])。

        该功能返回一个用于所期望的文件的FCB,这个FCB不仅大小合适而且

    是未打开的,同时,该功能还返回一个指向该文件的文件名之后第一个字符的

    指针(如果在几个文件名之中的某个文件名内分析命令行,那么该功能的作用

    是很明显的)。在执行该功能时,系统会自动地把星号字符,转换成一个或多个

    问号字符,以终止文件名或扩展名。

        由于该功能是一种FCB功能,它不可能与路径名兼容,因此,在文件名中

    不能出现有目录。该功能可以只分析当前目录中的文件,并且可通过表16.4

    中给出的分析标志来控制文件名的解释。

                            表16.4分析控制标志

            位

                                    含    义

    76543210

    . . . . . . . 0         停止分析,表明已找到文件分隔符

    . . . . . . . 1         忽略前导分隔符

    . . . . . . 0.         如果字符串中不含驱动器字母,则把FCB中的驱动

                            器ID置为0

    . . . . . . 1.         如果字符串中不含驱动器字母,则让FCB中的驱动

                            器ID保持不变

    . . . . . 0. .          如果字符串中不含文件名,就把FCB中的文件名设

                            置为8个空格(20H)

    . . . . . 1. .          如果字符串中不含文件名,就让FCB中的文件名保

                            持不变

    . . . . 0. . .          如果字符串中不含扩展名,就把FCB中的扩展名字

                            设置为3个空格字符

    . . . . 1. . .          如果字符串中不含扩展名,就让FCB中的扩展名保

                            持不变

      一旦使用FCB功能,就可用该功能来正确地设置FCB。该功能的作用是

正确地格式化FCB、并且为其作打开的准备。要想使用FCB的打开或创建功

能,必须将ES中的指针移动到DS:DX上。

      如果所分析的对象中不含非法的文件名,该功能就会返回指针ES:DI,

以便ES:DI+1指向空白字符。

 

504页

时钟

Int 21h           功能2Ah                               版本1

                  获取系统日期

从系统中获取年、月、日以及星期几

调用寄存器: AH              2Ah

返回寄存器: CX             年份(1980-2099)

                DH          月份(1-12)

                DL          日期(1-31)

                AL          星期几(0=星期天,1=星期一,等等)

                            DOS版本1.1或更高的版本中才出现

                            这一功能

    注释:该功能返回DOS计算出的当前系统日期。这只是对DOS内部时钟的

    检查,而不是访问已安装的实时时钟/日历。按照惯例,如果系统安装有时钟/

    日历,那么在启动该系统时,或者人为地在系统中设置分隔时,就只能从AU-

    TOEXEC.BAT文件中检查时钟或日历。

      有时候,计算日期的系统可能会按照难以预料的方式偏离准确的时间。此

    时系统日期或时间就有可能未得到正确的更新,或者进程有可能干扰或改变

    内部系统时间。该功能就会因此返回不正确的日期(并且,不访问时钟或日期

    芯片,是不可能检查到这个日期的)。

        影响该功能准确性的一个常见错误表现在让系统连续超过24小时地运

    行或不使用(例如,超过一周)。由于只有当DOS检测到已设置的零点标志时,

    日期才能往前进,并且只有在调用有限的几个功能之一时才能实现这个过程,

    因此,在不使用系统时,日期不可能往前进。在下一次使用该系统时,虽然可检

    测到零点(midnight)标志,但是系统却没有记录这段时间已经过了几次零点,

    因而只把日期往后加一天。注意BIOS功能1Ah(获取时钟计数)的任务之一 

    就是重新设置零点标志。当系统经过一段时间的停用之后,最简单的日期较正

    办法是在再次使用该系统时,首先检查并改变系统记录日期。

        为了便于使用,该功能与功能2Bh(设置系统日期) 使用同样的寄存器格

    式。

时钟

Int 21h           功能2Bh                                版本1

                  设置系统日期

在不改变系统时间的前提下,把系统日期设置为某个指定的值

调用寄存器: AH            2Bh

505页

                CX            年份(1980-2099)

                DH            月份(1-12)

                DL            日期(1-31)

    返回寄存器: AL            00h,成功地设置了日期

                              FFh,日期无效,未设置

注释:该功能使用与获取系统日期功能同样的格式。如果已安装了时钟/日

    历,那么通过使用该功能就能够访问该时钟/日历,以获取当前日期并更新系

统日期。在没有安装时钟/日历的前提下,则可揭示用户输入日期并在操作系

    统中对其进行校正,这样,调用获取系统日期功能就能返回正确的日期。

      在文件操作过程中,可使用通过该功能设置的日期来屏蔽文件。

      如果计算机系统带有CMOS时钟,该功能就能令其设置它自己的日期。

时钟

Int 21h         功能2Ch                             版本1

                获取系统时间

获取按小时、分、秒和百分之一秒计算的系统时间

调用寄存器: AH          2Ch

返回寄存器: CH         小时(0-23)

            CL          分(0-59)

            DH          秒(0-59)

            DL          百分之一秒(0-99)

注释:同获取系统日期一样,获取系统时间功能是一种很有用,但却不需要我

们付诸大多注意力的功能。常常要用到该功能以报告出时间或在屏幕上显示

出时间。但是,在使用该功能时,应注意如下两点:

        该功能不从时钟/日历芯片中获取时间。它只获取DOS内部时间,这

        个时间是唯一一种像DOS的设置一样准确的时间。

        在许多系统上,系统的实时时钟精确度都不高,不能分辨出百分之一

        秒的时间。在这种情况下,该功能返回一种不连续的时间值来表示百

        分之一秒时间。

      使用用于非实际系统时间的时间功能的应用程序没有必要去担心时间设

置情况。在有些程序中,也可用先把DOS时间设置为0然后再检查所经过的

时间的应用程序如计时器等。但是,在写入这类程序时,应防止其他程序从时

钟内获取当天的时间,如果先把DOS的时间设置为0,再用应用程序来记录

经过的时间,那么当其他程序返回错误的系统时间时,正在使用这种程序的用

户就会受到干扰。

      该功能使用的寄存器格式与用功能2Dh(设置系统时间)的寄存器格式是

 

506页

相同的。

时钟

Int 21h         功能2Dh                               版本1

                设置系统时间

在不改变系统时间的前提下,把系统时间设置成指定的小时、分、秒和百分之

一秒

调用寄存器: AH                2Dh

                CH            小时(0-23)

                CL            分(0-59)

                DH            秒(0-59)

                DL            百分之一秒(0-99)

返回寄存器: AL                00h,时间设置成功

                              FFh,日期无效,未设置

注释:在下列情况下,设置系统时间是有益处的:

      ·程序配备有时钟/日历,并且能从芯片时钟准确地设置出日期和时间

      ·程序要求用户设置某个具体时间

      ·用时钟记录经过的时间;先把时钟调整为零,然后用它来显示或记录

        经过的时间而不是系统时间

    这种寄存器格式(与用于功能2Ch——获取系统时间的寄存器格式相同)

允许用户获取时间,寻问有关时间的问题,并且接着更新已改变的时间。在有

专人使用的情况下,最好将时间精确到上下波动不超过1秒的范围内。应尽可

能地按百分之一秒来计算经过的时间,典型的用户都希望采用这种精确度。设

置更高的时间精确度,例如用于天文学方面的应用程序)要求用到特殊的同步

化技术。

    从时钟/日历芯片中或从时间服务器如WWV无线电链络中计算出时间

的程序能把时间精确到百分之一秒。在要求一致的基础上,一些计算机不能返

回具有这种精确度的时间,因为实时时钟的精确度不够。

    如果计算机拥有CMOS时间,该功能就可引发CMOS时钟设置它自己的

时间。

时钟

Int 21h         功能2Eh                             版本1

                设置检验标志

激活DOS检验标志;在写给磁盘时打开这种标志会引导另外的CRC检查(周

期性冗余检查)并增加磁盘传送时间

507页

调用寄存器: AH              2Eh

                AL           00h,关掉检验标志

                            01h,打开检验标志

                DH           00h(早于3.0的DOS版本)

    返回寄存器:无

    注释:怎样才能不通过检验磁盘写而证实它们是正确的呢?虽然能对所有写

    给磁盘的数据强制实行磁盘检验,但是,同平常的操作相比,这种操作过程要

    花去两倍以上的时间。在有些非IBM的BIOS分支系统上,甚至不支持这种操

    作。

        那么到底为什么不这样做呢?很明显,是出于时间上的原因。在没有必要

绝对保证每个磁盘写都正确的时候,就应关掉检验标志。仅仅当面对十分关键

    的功能时,才有必要设置这一标志,但使用之后也应将其关掉。

        即使打开检验标志,也不能绝对保证所写的数据都是正确的,因为检验过

    程不是把所写的数据同支持写的数据进行逐字节地比较而实现的。在这一过

    程中,系统等到完成一个周期才读出所写入的数据,并通过磁盘控制器计算出

    CRC值,然后再把计算出的CRC同第一次把数据写给磁盘时所计算出的值

    进行比较。

        这一过程不能保证数据在内存与磁盘控制器之间的传递时不会出现任何

    错误;该过程只能证实控制器写给磁盘的值与用于计算出第一个CRC的值相

    等,然后再将同一计算过程重复一遍。但是,由于大多数磁盘出错都会导致介

    质失效,这种出错阻止了系统从写入的正确数据中回读CRC,因此,这种检验

    毫无稗益。但是,对很关键的工作如数据的归档传送并随后从硬盘中擦除该数

    据,就必须采用唯一能保证绝对准确的数据传送途径,即:把复制的数据与初

    始数据进行逐字节的比较。

        可用功能54h来确定检验标志的当前设置情况。

磁盘

Int 21h           功能2Fh                               版本2

                  获取DTA地址

    获取用于文件控制块(FCB)文件操作的磁盘传送(DTA)指针的当前值。

    调用寄存器: AH        2Fh

    返回寄存器: ES:BX  指向DTA的指针

    注释:缺省DTA是在程序段前缀(PSP)中位于偏移值80h处的一个拥有

    128个字节的缓冲区。在实际应用中,这种DTA的大小对大多数程序来说都

    够用。但是,若要处理大型的记录或程序提出特殊的磁盘传送要求,那就应再

    设置一个DTA。

      功能1Ah的作用是设置DTA;功能2Fh则能告诉你DTA位于什么地

 

508页

    方。但是,功能2Fh却不能告诉你DTA有多大(这种信息是必须有的)。在实

    际操作中,如果不能确定DTA的大小是否够用,那么唯一的选择就是自己把

    一个能够处理特定操作的大内存块设置为DTA。

系统

Int 21h             功能30h                                     版本2

                    获取DOS版本号

    返回DOS版本号作为参照,以便应用程序确定软件系统的容量;早于2.0以

    前的DOS版本都返回版本号0。

    调用寄存器: AH            30h

                AL            版本标志

                00h           OEM号

                01h            DOS版本标志

    返回寄存器: AL           主版本号(2.3)

                AH            次版本号(2.1=10)

                BH             OEM号或DOS版本标志

                BL: CX       24位的系列号

    注释:对于直接与DOS打交道的程序员来说,知道DOS版本号是十分有必

    要的,它允许程序员为已安装的系统版本定制程序。把该功能返回的版本号加

    上DOS版本2.0就可能够检验系统能否支持我们所需要的DOS调用。(注

    意:若使用Microsoft C和Borland C++,这些值就能用作全局变量)。

        如果程序运行的DOS版本早于2.0,该功能返回的主、次版本号都为0。

    这样的值能立即告诉你如下的重要信息,即:无路径名、无目录并且无硬盘支

    持。如果在为DOS版本2.0编写程序,但随后却发现你拥有只是DOS的1.x

    版本,那么此时必须采取以下措施:

        1.通过Int 21h,功能09h返回一个错误信息。

        2.通过Int 21h,功能00h退出该程序。

        如果打算支持早于2.0的DOS版本,上述信息将限制你使用某些DOS

    功能。

        在编写程序时,要注意的不只是DOS 1.X提供的限制。因为程序员们已

习惯于使用各种功能来扩展他们的能力,就好像这些功能都能用得上。DOS

    版本3.3增加了一些功能,并允许增加打开文件的数目,以及清除磁盘的文件

    缓冲区。在数据库程序中,使用这些功能可使数据库更易于写。但是,没有

    DOS版本3.3的用户如果不能找到其他途径来解决DOS早期版本中存在的

    各种问题,他们就只能步别人的后尘(并且有可能不是DOS将来版本的买

    主)。

        如果返回了DOS版本标志,那么位3置位表明MS-DOS是在ROM中运

509页

行;否则,表明它是在RAM中运行的,其余的位都未定义。如果返回了OEM

号,是与OEM相关的系列号都出现在BL:CX中,如果没有使用OEM,BL:

CX的值为0。

      DOS版本号通过MS-DOS SETVER命令而设置的,与功能3306h返回

的版本号相比,这个值可能有出入。

系统

Int 21h             功能31h                                   版本2

                    终止并驻留

终止程序并把控制权返回给父进程

调用寄存器: AH              31h

                AL        返回代码

                DX          要保留的内存大小(按节计算)

返回寄存器:无

注释:终止并驻留实用程序是如此的普遍,以致我们很难找出有哪个系统不

使用一个或多个这样的实用程序。除了可用作诸如弹出式计算器、日历和便笺

(notepad)之类的实用程序之外,还可用TSR来为程序序列提供常规的子例

程服务。建成了一种可通过调用指定的中断来激活的功能库之后,就能为此程

序提供标准的实用程序例程,而不必直接将例行程序与程序进行连接。这种功

能减少了模块的大小,并加速了装载模块的进程。

      TSR的作用是终止程序的操作(像功能4Ch一样)但却不把程序占用的

内存返回到由DOS管理的内存库。这样便允许程序继续保存活性并且当它将

自己联结上某种中断时便能被再次激活。例如,将某种程序联结上时钟中断时

就能激活该程序并在屏幕上显示出时钟。并且,如果按下某个键或者程序调用

了中断功能,同样也能激活该程序。

      该功能可替代最初出现在DOS版本1中的Int 27h TSR功能。这种初始

的TSR功能只允许最多64K的内存供自己享用,并且不提供返回代码。而功

能31h则允许它自己使用超过64K的内存并能控制返回代码,通过功能

4Dh,这种返回代码就能供程序的父程序使用。这样便允许批处理文件控制自

身内ERRORLEVEL参数变量的执行情况。

      在启动程序时,这种TSR功能就试图把通过DX寄存器请求的内存分配

给已驻留的程序。但该功能不处理通过调用功能48h而分配全进程的内存。功

能31不关闭程序打开的任何文件,而是让程序打开的文件继续保持打开状

态。通过程序段前缀(PSP)中某个未公开的区域就能把句柄功能与当前活动

的进程联系在一起。当该TSR功能不在活动的进程中时,它就会通过使用当

前活动的进程所打开的句柄来引用文件。但是这种方法不适用于文件控制块

(FCB)功能,因为这种功能是通过进程自身的区域来缓冲的。(关于FCB的具

 

510页

体情况可参见第9章“目录和文件”。)

      所有使用句柄功能来处理文件和设备(并且在弹时或者相反在活动时需

要使用句柄功能)的TSR,在使用句柄之前必须通过使用未公开的功能50h

和51h来转换DOs关于当前活动进程的定义。否则,就会出现我们不希望出

现的结果,并且还可能严重地毁坏其他程序或数据。

系统:

Int 21h             功能32h                                     版本2

                    获取驱动器参数块

    获取为指定磁盘驱动器定义字符特征的驱动器参数块;在DL=0时,该功能

    的作用与功能1Fh的作用相同。

调用寄存器: AH              32h

                DL          驱动器号(0=缺省;1=A;以此类推)

    返回寄存器: AL         如果驱动器无效则为FFh

                DS:BX     驱动器参数块的地址

    注释:使用该功能时,DS:BX便会返回磁盘参数块(DPB)的地址,这时所说

    的磁盘参数块是DOS用来确定在输入DL时,由DL指定的驱动器内磁盘的

    特定结构信息的参数块。

      表16.3给出了DPB的结构(参见功能1Fh)。注意,不同的DOS版本有

不同的DPB结构,而且,表中给出的每一项后面都注明了各自的用途,使用时

应先看看用途说明。

      由于该功能通过DS寄存器来给出返回值,因此,在调用该功能之前必须

先保存DS的值。

系统

Int 21h             功能33h     子功能00h                       版本2

                    获取Ctrl-Break标志

获取Ctrl-Break检验标志的状态

调用寄存器: AH              33h

                AL           00h,获取标志状态

返回寄存器: DL              00h,关掉Ctrl-Break检验标志

                            01h,打开Ctrl-Break检验标志

注释:除了用于少数的I/O功能外(参见字符I/O功能01h-0Ch),在Int 21h

功能的处理过程中,大部分时间不对Ctrl-Break或Ctrl-C字符进行检查。一旦

开始检查,除了少数几个纯设置或获取标志数的功能外,对其余的Int 21h功

能都要进行检查。子功能00h通过DL返回Ctrl-Break标志的当前状态、至于

511页

如何改变Ctrl-Break检验标志的状态,可参见子功能01h。

    在允许检验的前提下,如果找到了Ctrl-Break或Ctrl-C,那么程序的控制

权就被传递给用于Int 23h的处理程序。此时,可用你自己的某个功能来替换

出Int 23h处理程序,并处理Ctrl-Break或Ctrl-C,而不是禁止Int23h处理程

序。

    这里值得注意的是,Ctrl-Break/Ctrl-C标志是一种系统的全局性标志,它

能影响在DOS系统上运行的所有程序。由于是一种系统全局标志,因此在对

其进行处理的过程中,必须加以小心,因为它有可能影响到其他的进程、却不

影响令该功能激活或失活的进程。

系统

Int 21h           功能33h   子功能01h                   版本2

                  设置Ctrl-Break标志

设置Ctrl-Break/Ctrl-C检验标志的状态

调用寄存器: AH            33h

              AL           01h设置标志状态

              DL           00h,已停止对Ctrl-Break的检查

                             01h,正在进行Ctrl-Break检查

返回寄存器:无

注释:除了用于少数几种I/O功能外(这种例外情况可参见字符I/O功能

01h-0Ch),在Int 21h功能的处理过程中,很少检查Ctrl-Break/Ctrl-C字符。

当检查开始时,除了少数几种纯粹只设置或获取标志数据的功能外,对其余的

Int 21h功能都要进行检查。子功能01h则能建立起Ctrl-Break检验标志的当

前状态;关于检验其状态的信息可参见子功能00h。

      在允许检查时,如果找到了Ctrl-Break/Ctrl-C,那系统的控制权就被转交

给了用于Int 23h的处理程序。可以用你自己的程序来替换出Int 23h处理程

序并处理Ctrl-Break/Ctrl-C,而不用去禁止这种处理程序。

      值得注意的是Ctrl-Break/Ctrl-C标志是一种系统全局标志,它能影响

在DOS系统上运行的一切进程。由于是一种系统全局标志,因此,在对它进行

处理时应加以小心,因为它有可能影响其他进程,却对激活或禁止该功能的进

程不起作用。

系统

Int 21h         功能33h     子功能05h                 版本2

                获取引导驱动器代码

返回一种代码,该代码能反映出最近是从哪一个驱动器中引导系统的

512页

调用寄存器: AH                33h

                 AL            05h,获取引导驱动器代码

返回寄存器: DL               引导驱动器代码(1=A,2=B,3=C如此等等)

注释:通过版本4中才推出的这种功能,程序就能确定最近是从哪个驱动器

中引导系统的。每当系统进行自身的初始化时,这种信息就被保存在DOS内

核区域内。

系统

Int 21h             功能33h     子功能06h                     版本2

                    获取MS-DOS版本号

返回MS-DOS版本号修订版本号以及版本标志

调用寄存器: AH              33h

              AL             06h,获取MS-DOS的版本号

返回寄存器: BL             主版本号

              BH            次版本号

              DL          位0-2中为修订版本号;其余的位都是保留位,

                            并且值为0

              DH            版本标志。位3置位,表明MS- DOS在ROM中

                            运行;否则表明MS-DOS在RAM中运行。位4

                            置位,表明MS-DOS在上位内存区(HMA)内

                            运行;否则表明MSDOS在常规内存中运行。

                            其余的位都用作保留,其值都为0。

注释:通过SETVER不能改变MS-DOS的版本号

系统

Int 21h             功能34h                                     版本2

                    返回InDOS标志的地址

一种内部的DOS标志用于表明DOS何时在处理Int 21h功能

调用寄存器: AH              34h

返回寄存器: ES:BX       指向InDOS标志的指针

注释:一旦DOS进入了Int 21h功能,DOS就会加上InDOS标志,当DOS退

出时,它又会失去这种标志。 DOS和终止并驻留(TSR)实用程序都用这种标

志来确定DOS是否在内核中并且是否在处理Int 21h功能。当TSR实用程序

确定DOS在处理其他功能时,它可选择做以下两事情之一:

      ·继续这一进程,因为此时不需要使用Int 21h功能。

513页

          拒绝处理,因为需要用到Int 21h功能。

        值得注意的是操作系统内核不完全是可重入的。因此,当操作系统正处在

    内核中时如果出现了中断,服务例程就不能使用Int 21h功能来处理中断,因

    为对一种功能的调用可能与前面的调用发生冲突。在这种情况下,稍不小心就

    会冲毁系统,不过,也绝对没有必要去翻出中断处理程序来处理此时的中断。

        出于操作上的需要,小部分DOS内核代码的确可通过Int 21h接口来使

    用其他部分的代码,并且把InDOS标志用作防止代码出错的信号。此时In-

    DOS标志还可保证正式的TSR程序如PRINT.COM及其类似的程序能正常

    运转。但是,这种标志也常常出现错误引导的情况。

        当DOS在等待键盘输入时,它在循环过程中是空闲的,并且一旦有字符

    输入进来它就会读取这些字符。因此,只要DOS尚处于等待状态,就能安全地

    使用文件处理及其他一些功能,即使InDOS标志指示的是其他情况。为了让

    你清楚可安全地使用这些功能,DOS在它的输入循环中不间断地调用Int 28h

    (键盘忙碌循环)。TSR能截获Int 28h,这样,当Int 28h缺省时,它就成为一个

    指向IRET的指针,并且只要还在正常运转,它就会检查要做的事情。

        例如,如果按下某个热键启动了TSR之后,但它却发现DOS正在执行

    Int 21h功能,因为已设置了InDOS标志,此时,TSR就会设置一种内部的标

    志来表明“我已被调用,但我不能做任何事情”。无论何时,只要调用Int 28h,

    就能检测到InDOS标志。反过来,如果设置InDOS标志,处理程序就会立即

    转向TSR部分以实现被请求的功能。

        在时钟计数期间,TSR还能截取时钟中断,并检查InDOS和TSR引用标

    志。这样做的目的是为了防止在首次调用TSR时,出现Int 21h功能(而不是

    字符I/O功能)是活动的情况。因为一旦出现这样的情况,时钟中断就能检测

    到InDOS标志的清除以及TSR引用标志的置位。然后,时钟中断根据实际情

    况确定可以实现的请求功能。

        但是,在DOS版本2中使用Int 28h仍然会莫名其妙地导致系统冲毁。究

    其原因在于版本2在未来得及把控制权调度给任何被请求的功能之前已先切

    换到它自己的内部堆栈上;这样,当DOS在处理00到0Ch范围内的某个功能

    时(在调用Int 28h时,DOS几乎都在处理这个范围内的某个功能),如果出现

    了调用其它功能的情况,那么第二个堆栈就会切换出来,其结果是破坏了初始

    功能调用所需要的信息。

        防止的办法十分简单但却极有意思:即通过操纵DOS的关键出错

    (CritErr)标志,令DOS相信它正在处理一种关键性的错误。在调用某个功能

    之前,先设置CritErr标志能强迫DOS改变用它自己的内部堆栈。但在退出该

    功能之后,必须将这一标志恢复到它的初始值。

        在DOS版本3中,系统在进行任何堆栈切换之前,首先修改DOS调度代

    码以检测起作用的功能;如果调用程序请求这些功能中的任何一个DOS都会

    使用调用者自己的堆栈,从而可避免出现问题。在DOS版本4中,这种调度代

 

514页

码依然保持未变。

      CirtErr标志只是一个字节,它表明DOS已遇到了严重出错的情况,并且

正在处理Int 24h(关键出错)处理程序例程。为了让这种处理程序尽可能地应

    用到更多的DOS功能中去,就可设置CritErr标志并导致DOS调度代码以使

    用备用的内部堆栈而不是普通的堆栈空间。虽然调度代码的方式与完全可重

入的编码方式不同,但这样做能允许有限的功能重新使用调度的代码。

      在版本2至版本4之间的所有版本中,CirtErr标志与InDOS标志是毗邻

    的。遗憾的是,在版本2和版本3之间,CritErro标志的位置出现了变动。在版

    本2中,它是位于紧挨在InDOS标志之上的一个字节,而在版本3和版本4

    中,它却变成了紧跟在InDOS标志之下的一个字节。

    注意:若从Int 28h处理程序中进行调用,该功能就会导致出现一些问题。该

          功能的正确用法应是在它成为常驻功能之前,先安装TSR。基于这一

          点可使用所有的DOS功能来确定适用于CritErr的正确位置。使用这

          种功能可获取和保存InDOS标志的地址,确定DOS版本号,并根据

          要求相应地增加或消除CritErr标志,并把该标志的地址保存在一个

          单独的指针内。

      这样,当TSR弹出时,它就能使用它自己的InDOS指针以确定DOS是

    否为活动的,并且如果有必要,它还可用它自己的CritErr指针来获取该标志

    的当前值。然后将该值保存起来,并设置CritErr标志以强制使用备用的堆栈、

    着手处理一切急需处理的事情,并在退出之前恢复初始的标志值。

系统

Int 21h           功能35h                                 版本2

                  获取中断向量

获取用于指定中断的中断处理程序地址

调用寄存器: AH              35h

              AL            中断号

返回寄存器: ES:BX       指向中断处理程序的指针

注释:对某个指定的中断来说,中断处理程序地址虽然是绝对可用的,但是,

该功能却是获取中断向当前设置的唯一可靠的途径。该功能可保证顺利地完

成获取工作并为向量返回一个可靠的值,其他的程序例如终止驻留(TSR)实

用程序则可在该功能顺利地返回了值之后改变这一中断向量。当单用户、单任

务操作的系统出现在该功能的使用范围内时,上述过程却会发生。

      当设置一道程序以便从某个中断处理开始工作时,就应使用功能35h来

确定该中断的初始设置,以便在完成工作时可将该中断还原。在做这项工作时

必须细心,因为有可能出现与TSR或其他中断处理程序发生冲突的情况。如

515页

果能记住某个中断值,并且随着TSR的启用而改变了这个值,那么就要以采

用一种能禁止该TSR的方法来替换出这一中断。

      为了防止出现冲突,应一直打算恢复的中断向量同程序最初在该向量中

设置的值进行对照。如果发现这些值不相同,那么说明自从保存了这个值以

后,其他的程序已修改了这个值,并且此时已无法安全地实现恢复操作或者不

能安全地从内存中撤走程序。如果当前值与初始值相符合,就可以安全地把中

断恢复到其初始值。

磁盘

Int 21h             功能36h                                   版本2

                    获取自由磁盘空间

    除了有选择地获取磁盘的有关信息,还获取该驱动器上有用的磁盘空间

    调用寄存器: AH          36h

                DL        磁盘驱动器(0=缺省驱动器;1=A,如此等等)

    返回寄存器: AX         每簇的扇区数(如果驱动器无效,则为FFFFh)

                BX          有用的簇数

                CX          每扇区的字节数

                DX          驱动器上的簇数

    注释:该功能与功能1BH和1Ch相似,其作用是返回可用来确定磁盘上有用

    空间的基本信息。

      使用该功能时,可从指定要检查的磁盘驱动器着手。此时,可获取如下的

原始信息:

        ·每簇的扇区数

        ·可用的簇数

        ·每扇区的字节数

        ·驱动器上的总簇数

      得到这些信息后,就可按下面的算式计算出可用的空间量:

(有用的簇数)*(每簇的扇区数)*(每扇区的字节数)

所得的结果即是该驱动器上可用的字节数。将这一数字除以1024可得到千字

节数,或除以记录长度得到可用于数据库等的记录数。

      要得到磁盘上有用的空间总量,可按下面的算式计算:

(驱动器上的总簇数)*(每簇的扇区数)*(每扇区的字节数)

得出结果后,就可写出一种功能来打印出如下信息:

          xxxx bytes free out of yyy

 

516页

功能1Bh和1Ch可返回与上述类似的信息。

STOP

Int 21h         功能37h   子功能00h                   版本2

                获取开关字符(Switchar)

获取当前开关字符

调用寄存器: AH              37h

              AL           00h

返回寄存器: AL              FFh,表示AL子功能不在0-3这个范围内

              DL            开关字符

注释:开关字符是DOS在把字符串分析成指定的命令开关时所使用的字符。

通常情况我们都把开关字符设置成斜线(/),但是,根据应用程序的要求我们

也可将它设置成其他字符。

STOP

Int 21h           功能37h     子功能01h

                  设置开关字符

允许将当前开关字符复位

调用寄存器: AH              37h

              AL           01h

              DL            开关字符

返回寄存器: AL              FFh,表示AL子功能不在0-3这一范围内

注释:开关字符是以DOS在把字符串分析成指定的命令开关时所使用的字符,

通常情况都用斜线(/)来表示,但也可根据应用程序的需要,将它设置成其他

的字符。

      如果使用这种功能,首先必须确定当前的开关字符(子功能0)并将其保

存起来,以便在完成了程序之后,能将当前开关字符恢复到它的初始化状态。

STOP

Int 21h           功能37h   子功能02h                     版本2

                  读取设备的可用性

    指出设备名称前面有无必要加上假路径名/DEV/

    调用寄存器: AH          37h

                AL         02h

    返回寄存器: AL          FFh,表示AL子功能不在0-3这个范围内

                DL        0,/DEV/必须加在设备名之前

 

517页

                              <>0,不必把/DEV/加在设备名的前面

    注释:设备可用性标志(仅仅在版本2中采用)控制一种与UNIX类似的功

    能,这类功能通过强迫为各种设备加上假目录DEV从而使得文件和设备具

    有同样的名称,当该标志为00时,表示只能在DEV目录中打开或关闭设备;

    若为非零标志,则表示允许设备领先于文件名,这意味着在系统内,所有文件

    都不会有与设备相同的名字。在版本3内,这种标志被永久地设置为非零值,

    并且禁止子功能3的使用。

STOP

Int 21h              功能37h     子功能03h                 仅用于版本2

                    设置设备的可用性

    确定在设备名前面有无必要加上假路径名/DEV/

    调用寄存器: AH            37h

                AL           03h

                DL          0,必须把/DEV/加在设备名之前

                              <>0,没有必要把/DEV/加在设备名之前

返回寄存器: AL             FFh,表示AL子功能不在0-3这个范围内

                DL          设备的可用性标志(同输入一样)

注释:设备可用性标志(仅用于版本2)控制着一种与UNIX类似的功能,该

功能通过强制地为所有设备加上假目录DEV;从而允许文件和设备具有同样

    的名称。该标志为00时,表示只能在DEV目录内打开或关闭设备;任何非零

    标志都允许设备领先于文件名,这就意味着在整个系统内没有任何文件拥有

与设备相同的名字。版本3已将这一标志永久地设置成了非零值,并且已禁止

    了子功能3的使用。

系统

Int 21h             功能38h                                     版本2

                    获取/设置当前国家信息

获取当前国家信息;在DOS 3.0以及更高的版本中还允许设置当前国家信息

调用寄存器: AH              38h

              AL           00,获取当前国家信息

                            在DOS  3.0以及更高的版本中

                            01-FEh,规定的小于255的国家代码

                            FFh,国家代码出现在BX寄存器中

              BX            如果AL=FFh则为国家代码

              DS:DX      指向信息缓冲区的指针

              DX            为FFFFh以设置国家代码(以DOS3.0以及

 

518页

                              更高的版本)

    返回寄存器:进位标志清除表示成功

                BX            国家代码(仅用于DOS版本3)

                DS:DX       指向返回的国家信息的指针

                  进位标志置位表示出错

                  AH          错误代码

                              02h,无效的国家(文件未找到)

    注释:由于DOS是一种国际性的磁盘操作系统,因此,为DOS设计的程序必

    须能在国际性的设置中工作。该功能的作用是通知程序对各种用于显示信息

    的国家参数应分别采用什么样的表现方式。例如,日期格式类型的国家参数用

    字节0和1进行编码。

        当该功能获得了与国家有关的信息时,它就会通过这种信息返回一个指

    向32个字节的缓冲区的指针。在DOS版本3以及更高的版本中,该功能还可

    用来设置供其他程序使用的国家信息。

        国家代码通常为国际性的电话前缀代码。一些较典型的代码(例如,

    American Samoa为684,Portugal为351)几乎可在所有电话号码簿的前部找

    到。值得注意的是,这些号码可以大于255。为了适应这种情况,当AL寄存器

    被设置为FFh时,该功能可使用BX寄存器来保存这些代码。

        表16.5列出了国家信息表的格式,这些信息都是DS:DX指针所指向

    的信息。

                        表16.5国家信息缓冲区中的内容

位偏移值              长度          意    义

    DOS版本2

    00h                   字              日期和时间格式

                          0=美国          月日年,时时:分分:秒秒

                          1=欧洲          日月年,时时:分分:秒秒

                          2=日本         年月日,时时:分分:秒秒

    02h                   字节            货币符号

    03h                   字节            零

    04h                   字节            千分隔符

    05h                   字节            零

    06h                   字节            小数分隔符

    07h                   字节            零

    08h                    18字节         保留

    Dos版本3或版本4

    00h                   字              日期格式

                          0= 美国         月日年

519页

位偏移值              长度            意    义

                        1= 欧洲          日月年

                        2= 日本         年月日

02h                      5字节          货币符号串(ASCIIZ)

07h                     字节            千分隔符

08h                     字节            零

09h                     字节            小数分隔符

0Ah                     字节            零

0Bh                     字节            日期分隔符

0Ch                     字节            零

0Dh                     字节            时间分隔符

0Eh                     字节            零

 0Fh                字节              货币格式

                                        00h=在货币前面的符号,中间无间隔

                                        01h=在货币后面的符号,中间无间隔

                                        02h=在货币前面的符号,间隔一个空格

                                        03h=在货币后面的符号,间隔一个空格

                                        04h=代替小数分隔符的符号

10h                   字节              小数点之后的位数

11h                   字节              时间格式

                                        位0=0,12小时钟

                                        位0=1,24小时钟

12h                   双字              大小字变换调用地址

16h                     字节            数据列表分隔符

17h                     字              零

18h                      8字节          保留

DOS版本5

00h                     字              日期格式

                        0=美国         月日年

                        1=欧洲         日月年

                        2=日本         年月日

02h                      5字节          货币符号串(ASCIIZ)

07h                      2字节          千分隔符(ASCIIZ)

09h                      2字节          小数分隔符(ASCIIZ)

0Bh                    2字节           日期分隔符(ASCIIZ)

0Dh                      2字节          时间分隔符(ASCIIZ)

0Fh                     字节            货币格式

                                         00h=在货币前面的符号,中间无间隔

                                        01h=在货币后面的符号,中间无间隔

                                        02h=在货币前面的符号,间隔一个空格

                                        03h=在货币后面的符号,间隔一个空格

                                        04h=代替小数点分隔符的符号

10h                   字节              小数点之后的位数

520页

位偏移值              长度            意    义

11h                   字节              时间格式

                                      位0=0,12小时时钟

                                        位0=1,24小时时钟

12h                 双字            大小字变换调用地址

16h                    2字节            日期列表分隔符(ASCIIZ)

18h                   10字节            保留

      表中偏移值12h处的大小写变换调用地址是格式化过程的远地址(段:

偏移值),这里所说的格式化过程是指实现国家专用的,大于7Fh的大小写字

符值变换的过程。必须通过在AL寄存器中进行字符变换才能调用这一过程,

调整后的值可通过AL寄存器来返回。

磁盘

Int 21h             功能39h                                     版本2

                    创建子目录

在指定的驱动器和路径位置上创建子目录

调用寄存器: AH              39h

              DS:DX      指向ASCIIZ路径说明的指针

返回寄存器:进位标志清除表示成功

              进位标志置位表示出错

              AX            出错码

                            03h,路径未找到

                            05h,访问被拒绝

注释:除了通过该功能以及其它目录功能(功能3Ah和3Bh)来控制目录项

外,DOS没有采用别的办法。这种特殊的功能允许创建新目录,新的目录采用

目录路径名,必要时加上驱动器符号。

      如果目录已经存在,或如果路径名中的任何元素不存在,或者如果目录为

根目录并且根目录已满的话,该功能就会返回一个错误并且不会去创建所请

求的目录。

      在网络环境中,必须拥有创建权限才能创建子目录。

磁盘

Int 21h             功能3Ah                                     版本2

                    删除子目录

如果子目录是空的,就将其删除

521页

    调用寄存器: AH          3Ah

                DS:DX    指向ASCIIZ路径说明的指针

    返回寄存器:进位标志清除表示成功

                进位标志置位表示出错

                AX          出错码

                            03h,路径未找到

                            05h,访问被拒绝

                            10h,当前目录

    注释:该功能是三种能操纵其他目录中目录项的功能之一。它允许删除指定

    的目录,但前提是该目录项存在并且是空的,而且要删除的目录不能是缺省目

    录。

        在网络环境中必须拥有创建权限才能删除子目录。

磁盘

Int 21h           功能3Bh                                  版本2

                  设置目录

设置当前目录或缺省目录,以便与特定的字符串匹配

调用寄存器: AH       3Bh

              DS:DX    指向ASCIIZ路径字符串的指针

返回寄存器:进位标志清除表示成功

              进位标志置位表示出错

              AX            出错码

                          03h,路径未找到

                          05h,访问被拒绝

                          10h,当前目录

注释:该功能允许把程序放置在目录系统中的某个指定位置。

      对于在特殊目录中运行的程序来说,一种行之有效的技术是在使用该功

能来设置新的目录区域之前,先用功能47h来确定当前目录,并把这一信息保

存起来。这样,当程序运行完毕后,它能把目录返回到初始状态。不过,很少有

程序实现这一步。

磁盘

Int 21h           功能3Ch                                   版本2

                  创建/截短文件(句柄)

如果文件不存在时可创建指定的文件,或者当文件的确存在时可把该文件长

度截短到零。

522页

    调用寄存器: AH            3Ch

                CX            文件属性

                  DS:DX     指向ASCIIZ文件说明的指针

    返回寄存器:进位标志清除表示成功

                  AX          文件句柄

                  进位标志置位表示出错

                  AX          出错码

                              03h,路径未找到

                              04h,无可用的句柄

                              05h,访问被拒绝

    注释:该功能是文件操作过程的一种很基本的功能。它在面向句柄功能中的

    作用就像功能16h在文件控制块(FCB)功能所起的作用一样。其作用是当文

    件不存在时,可创建出命名文件或当文件存在时能将其长度截短到零。所期望

    的文件是用ASCIIZ字符串来命名的,其中可以含有驱动器以及路径标识符。

    该功能返回的是16位的文件句柄。文件句柄用于进一步对文件进行访问。新

    创建的文件都有文件属性,这一属性通常被设置在CX寄存器中。下表列出了

    各种不同的值以及与它们相匹配的文件类型。

    值                相匹配的文件类型

    00h               普通文件

    02h                 隐藏文件

    04h                 系统文件

  06h                 系统和隐藏文件

      一旦不需要截短功能,那么根据所运行的DOS版本可相应地作出如下三

种选择:

      ·若使用的是DOS版本2,则可通过功能3Dh来打开文件,如果功能

        3Dh失败,就调用功能3Ch来创建文件。

      ·若所使用的为DOS版本3,则可用功能5Bh来创建文件。如果功能

        5Bh失败,就调用功能3Dh来打开文件。

      ·对于DOS版本4,还可以使用功能6Ch,这一功能能在单项功能中给

        出全部的文件打开选项。

      无论选用的是哪种方法,都需要仔细考虑一下这种功能的使用方法。曾有

不少的程序员在不恰当的时间里调用了这种功能,其结果是毁掉了许多很重

要的数据。

      导致该功能失败的原因不外乎如下几种:即路径名中缺少路径元素;正

在根目录中创建文件并且根目录已满;以及虽有相同的文件名但却为只读文

523页

    件等。

        使用该功能来创建文件时,往往通过返回读/写许可权、把文件作为普通

    文件来创建。如果有必要,还可用功能43h来改变文件的属性。不能用该功能

    来创建子目录和卷标。

        在网络环境中,必须拥有创建权才能创建或截短文件。

磁盘

Int 21h             功能3Dh                                 版本2

                    打开文件(句柄)

打开指定的文件并返回一个可用来引用该打开文件的文件句柄(16位的数

字)。

调用寄存器: AH            3Dh

              AL        访问模式(DOS版本2)

                          访问和文件共享模式(DOS版本3以及

                          更高的版本)

              DS:DX     指向ASCIIZ文件说明的指针

返回寄存器:进位标志清除表示成功

              AX          文件句柄

            进位标志置位表示出错

              AX          出错码

                          01h,非法功能

                          02h,文件未找到

                          03h,路径未找到

                          04h,无可用的文件句柄

                          05h,访问被拒绝

                          0Ch,访问代码无效

注释:要想打开文件,首先要把文件名指定为ASCIIZ字符串。该功能可访问

的文件有三类:普通文件、隐藏文件或系统文件。寄存器AL可通知该功能:用

户希望访问的是哪一种文件。表16.6介绍了如何为DOS版本2和版本3设

置AL寄存器。

                      表16.6访问和文件共享模式

          位

                              含义

    76543210

      DOS版本2

. . . . . 000               读访问

. . . . . 001              写访问

. . . . . 010               读/写访问

524页

            位

                                含义

      76543210

DOS版本3和版本4

    . . . . . 000            读访问

    . . . . . 001             写访问

    . . . . . 010            读/写访问

    . . . . x. . .            保留

    . 000. . . .              共享模式——兼容模式

    .001. . . .              共享模式——读/写访问被禁止

    .010. . . .              共享模式——写访问被禁止

    .011. . . .              共享模式——读访问被禁止

    .100. . . .              共享模式——允许完全访问

    0. . . . . . .            子进程可继承的

    1.. . . . . .            仅当前进程拥有的

      在DOS版本3以及更高的版本中,除了可以请求读/写外,还可请求网络

访问(文件共享模式),并可指出所访问的文件是否可由可能执行的子进程来

继承。

      在返回时,文件一般是打开的,以便于系统按照期望的模式来访问该文

件,除非要访问的文件找不到或系统不允许所期望的模式(例如,把访问模式

设置为读/写模式来访问只读文件)。如果文件打开功能获得了成功,读/写指

针就会出现在打开文件的开始部分。

      在DOS版本2中,该功能只使用寄存器AL中的0-2位,其余的位都必须

要设置为零。在DOS版本3以及更高的版本中,由于装载了文件共享软件,

AL寄存器中又有4个位可供其他进程使用(位4-6,用于共享模式,位7为继

承位)。从不利的方面讲,文件共享出错诱发Int 24h(关键错误)返回出错代码

02h(驱动器未准备好)。

      如果把继承位置为1,就会使得被打开的文件成为打开该文件的进程的

专用文件。若继承位为0,打开文件就可供自该文件被打开后而涌现出的任何

进程使用。如果文件句柄为子进程所继承或被某个进程复制过,那么这个子进

程(或进程)也就继承了该文件句柄的所有文件共享模式。

      对出现在DOS版本3前后编写的大多数DOS软件来说,兼容模式(把位

37置为零)只是一种普通模式。只要软件在单个工作站上运行,文件访问过

程中就不会出现冲突。但随着联网软件的使用以及文件共享成为现实,兼容模

式已不再适合进行文件控制了。

      要想在网络环境中同其他程序一道工作,程序就得在打开调用过程中使

用共享模式,以便能在既定的编程任务所要求的限定条件下进行访问。

      通常情况下,应在兼容模式中使用FCB来打开文件,除非是为了只读访

525页

问而打开文件。在这种情况下,就只能在禁止写的共享模式中进行文件打开操

作。同时,通过句柄功能来为只读访问打开文件的操作也应在禁止写的共享模

式中进行。其他所有兼容访问模式都将禁止到全部文件访问完毕之后才进行

操作。

      为了正确地使用该功能,程序员必须熟知文件所要求的访问,并知道该文

件暗示出的各种非限制性的写访问。可能的模式有如下几种:

      ·禁止读/写。无论是在当前机器上还是在同一网络上的其他机器上,在

        这种模式下打开的文件不能被其他程序(或当前程序)再一次打开。为

          了便于控制面向关键更新的数据库操作,这种类型的访问是很有必要

        的。

        ·禁止写。对在这种模式下打开的文件,其他任何程序都不能将其打开

        来读。

        ·无禁止行为。没有禁止其他程序对此文件的访问(读或写)。

      在网络环境中,值得令人注意的是对数据文件的多个程序的访问。当多道

程序试图同时更新同一文件记录时,就会导致数据库出错。本书只介绍了不同

的程序之间应采用什么样的方法来协调文件访问。因此,要想进一步了解这种

协调机制,还应查阅一些关于数据库或操作系统的书籍。

磁盘

Int 21h           功能3Eh                                   版本2

                  关闭文件(句柄)

关闭先前通过文件句柄打开的文件

调用寄存器: AH            3Eh

              BX          文件句柄

返回寄存器:进位标志清除表示成功

              进位标志置位表示出错

              AX          出错码

                         06h,无效句柄

注释:该功能的作用是关闭先前用DOS文件处理功能打开或创建的文件。它

将句柄返回给系统使用,并同时实现对文件的所有更新。如果已经实现对文件

的改变,那么记录在文件目录项中的文件日期也就得到了更新。

      在实际操作过程中的一些成功的范例表明:程序应关闭它所打开的一切

文件以返回使操作系统正确地更新文件系统。当程序终止时,DOS虽然会自

动地关闭活动的文件句柄,但不能盲目地依靠DOS,尤其当希望程序变得可

移植时更是不能相信DOS。

      注意:在关闭文件句柄0时要格外小心,因为它是一种标准的输入设备

 

526页

(通常为键盘)。如果一不小心关闭了文件句柄,就会失去与键盘之间的通信,

除非立即重新打开CON设备。

磁盘

Int 21h           功能3Fh                                 版本2

                  读文件或设备(句柄)

从文件句柄参数指定的文件或设备中读出数据,然后把这种数据写入指定的

内存位置。

调用寄存器: AH            3Fh

              BX          文件句柄

              CX          字节数

              DS:DX    指向缓冲区的指针

返回寄存器:进位标志清除表示成功

              AX          读取的字节数

              进位标志置位表示出错

              AX          出错码

                          05h,访问被拒绝

                          06h,无效句柄

注释:基本的文件读操作能从文件中获取一定数目的字节并将其存放在指定

的缓冲区中。如果读操作成功地完成,但是AX小于CX,那么在检测到文件的

末尾(EOF)之前,会出现部分读取情况。如果在调用此功能时已经检测到了

EOF,那么系统会设置进位标志,只是此时AX寄存器的值将会是0。

      只要拥有全部的文件句柄调用,就可把设备当作文件来对待,因此,可使

用该功能来从字符设备如键盘中读出数据。只是在处理字符设备时还附加有

一些特殊的限定条件。如果字符设备处在一种组合的模式中(参见功能44h),

那么按下回车就可终止读操作(此时只读出一行)。

      在网络环境下,必须拥有读出权限才能读文件或设备。

磁盘

Int 21h           功能40h                                 版本2

                  写入文件或设备(句柄)

    把数据写入文件句柄所指定的文件

    调用寄存器: AH          40h

                BX          文件句柄

                CX          要写入的字节数

                DS:DX    为一指针,指向要写入的数据缓冲区

    返回寄存器:进位标志清除表示成功

527页

                AX          已写的字节数

                进位标志置位表示出错

                AX          出错码

                            05h,访问被禁止

                            06h,无效句柄

注释:使用文件句柄功能来把数据写入文件是一件十分容易的工作,只需指

定文件句柄,字节数和指向数据缓冲区的指针。接着,文件句柄功能把指定字

节写入文件中的当前位置。

      寄存器AX返回所写入的字节数,或者当该功能失败时返回出错代码。一

般情况下,通过AX返回的字节数与要写的字节数(CX寄存器返回的)是相同

的。如果写操作成功,并且AX的值小于CX的值,则表明只写下了部分记录;

同时,如果磁盘空间不够,也可能导致出现部分的记录写;在这种情况下,最好

的处理办法是用功能36h、1Bh或1Ch来检查可用的空间。如果对象文件被标

明为只读文件,那么该功能就会返回一个出错代码。

      在网络环境中,必须拥有写入权限,才能把数据写入指定的文件或设备。

磁盘

Int 21h         功能41h                             版本2

                删除文件

从系统中删除指定的文件

调用寄存器: AH              41h

                DS:DX    指向ASCIIZ文件说明串的指针

    返回寄存器:进位标志清除表示成功

                进位标志置位表示出错

                AX          出错码

                            02h,文件未找到

                            05h,访问被禁止

    注释:通过用E5h来把文件名中的第一个字节标记为目录项,该功能就能删

    除文件。如果在删除操作后未改变或创建其他文件,那么由于标记的存在,就

    有可能恢复,"被删除的" 文件。分配给该文件簇被返回给系统以便于再使用。同

    时,该功能不会重写实际文件。

        与文件控制块(FCB)删除功能(13h)不一样,该功能不允许使用通配符。

    如果想通过使用通配符的文件名来与文件相匹配,以便删除一组文件,那么就

    必须使用搜索功能(4Eh和4Fh)来逐个地定位这些文件。由于该功能允许访

    问位于目录中的文件,因而这一限制很容易克服。

        如果要删除的文件存在,但具有只读属性,或者不能找到要删除的文件,

    那么该功能会失败。

 

528页

    要想在网络环境中删除文件,则必须拥有创建访问的权限。

磁盘

Int 21h             功能42h                                     版本2

                    移动文件指针

改变文件的当前位置,并移动文件指针,令其指向某个与文件开头、文件末尾

或当前位置相关的位置。

调用寄存器: AH              42h

              AL          方法代码

                            00h,从文件开始处算起的偏移值

                            01h,相对于当前位置的偏移值

                            02h,相对于文件末尾的偏移值

              BX            文件句柄

              CX            偏移值中高位部分

              DX            偏移值中低位部分

返回寄存器:进位标志清除表示成功

              DX:AX       新文件指针的位置

              进位标志置位表示出错

              AX            出错码

                            01h,非法功能(文件共享)

                            06h,无效句柄

注释:该功能的作用是把文件读/写指针调整到指向一个新的位置,这个新位

置是通过偏离文件的开头,末尾或当前位置的距离来计算的。可以把这种偏移

值指定为一个32位的数字(指定的范围可一直到达(4096M)。在版本4之前,

还不可能在实际操作中使用这种大小的文件,因为操作系统限制用于单个磁

盘字的量最大不得超过32M。在版本4中,这种限制被取消了。当移动文件指

针时,应让该指针指向下一个从文件中读出数据或把数据写入文件中的位置。

      对该功能而言,较为实用的方法不是设置文件的位置,而是确定文件的大

小,可通过把寄存器AL置为2(相对于文件末尾的偏移值)以及把CX和DX

寄存器置为0(相对于文件末尾的偏移值),就能获得文件的大小。通过AX和

DX寄存器返回的位置表示按字节计算的实际文件大小。当然,要这样做,得

让指针处于文件的末尾。如果对返回的位置不满意,那么就得在读或写操作之

前,重新将该位置为所希望的位置。

      该功能的另一个重要的作用是实现从文件末尾开始的功能或附加功能。

首先,可用功能3Dh来打开文件,接着通过与用于确定文件大小相同的办法

(AL=2,CX和DX=0)来使用该功能,以便立即把读/写指针重新设置为指

向文件的末尾。

529页

    通过文件功能42h,可以把文件指针设置到文件开头之前或文件末尾之

后的某个位置。把文件指针设置到文件末尾之后是不会导致出错的,但若试图

从这个不存在的位置中读出数据就会导致出错。对文件末尾之后的位置进行

写操作会引起系统把更多的空间分配给该文件,从而使得该文件具有足够的

空间来容纳所写的内容。在进行读或写操作时,若把文件指针设置在文件的前

面,就会导致出错。

      如果在网络系统上使用该功能,并采用禁止读或无任何禁止的共享模式

来处理某个文件,那么拥有该文件的计算会调整文件指针信息。如果用任何其

他的共享模式来处理文件,则文件指针信息就会被保存在远程计算机上。

磁盘

Int 21h         功能43h                               版本2

                获取文件属性

获取文件的属性

调用寄存器: AH                43h

                AL             00,获取文件属性

                DS:DX      指向ASCIIZ文件说明的指针

返回寄存器:进位标志清除表示成功

                CX            属性字节(参见表16.7)

                进位标志置位表示出错

                AX            出错码

                              01h,非法功能(文件共享)

                              02h,文件未找到

                              03h,路径未找到

                              04h,访问被拒绝

注释:目录项的文件属性都是位映象的属性,如表16.7所示。

              表16.7用于功能43h,子功能00h返回的属性字节的位含义

          位

                              含义

    76543210

    . . . . . . . 1           只读文件

    . . . . . . 1.            隐藏文件

    . . . . . 1. .            系统文件

    . . . . 1. . .            卷标

    . . . 1. . . .            目录

    . . 1. . . . .            归档文件

    x x . . . . .             未使用

在各种目录项的属性中,通过该功能所不能访问的有用于卷标和子目录

 

530页

的目录项属性。

磁盘

Int 21h           功能43h   子功能01h                     版本2

                  设置文件属性

设置文件的属性

调用寄存器: AH                43h

                AL             01h,设置文件属性

                CX            新的属性(参见表16.8)

                DS:DX      指向ASCIIZ文件说明串的指针

返回寄存器:进位标志清除表示成功

                进位标志置位表示出错

                AX            出错码

                              01h,非法功能(文件共享)

                              02h,文件未找到

                              03h,路径未找到

                              05h,访问被拒绝

注释:表16.8中列出了文件属性的各种设置值。

                表16.8用于功能43h,子功能01h的各种属性设置

            位

                                                  含义

      654     3210

    . . .     . . . 1                           只读文件

    . . .     . . 1.                          隐藏文件

      . . .   . 1. .                            系统文件

    . 1.      . . . .                           归档文件

      使用该功能不能设置子目录或卷标。要想创建卷标,则必须使用文件控制

块(FCB)文件创建功能,并使用扩展的FCB。功能39h是唯一能用来创建目录

    的功能。

      在网络环境中,必须拥有创建访问权限才能改变除档案位以外的所有文

件属性位。改变档案属性位不要求具备任何限定的权限。

系统

Int 21h           功能44h                                 版本2

                    设备驱动程序控制(IOCTL)

把控制信息传送给设备驱动程序,或从设备驱动程序程序中获取控制信息。

调用寄存器: AH           44h

531页

                AL          设备子功能代码(参见表16.9)

                BX          句柄(子功能代码00h、01h、02h、03h、06h、07h、

                            0Ah、0Ch以及10h)

                BL          驱动器代码,0=默认,1=A,等等(子功能码

                            04h,05h,08h,09h,0Dh和11h)

                CX          要读取或写给的字节数

                CH          种类代码(子功能代码0Ch、0Dh、10h和11h)

                CL          功能代码(子功能代码0Ch、0Dh、10h和11h)

                DS:DX    指向缓冲区的指针(子功能代码02-05h)

                DS:DX     指向参数块的指针(子功能代码0Ch、0Dh、10h

                            和11h)

                DX          设备信息(子功能代码01h)(参见表16.9)

    返回寄存器:进位标志清除表示成功

                AX          已传送的字节数(子功能代码02-05h)

                AL          状态(子功能代码06-07h)

                00h         “未准备就绪”

                FFh         已就绪

                AX          值(功能代码08h)

                00h         可移动的

                01h         固定的

                DX          设备信息(子功能代码00)

                进位标志置位表示出错

                AX          出错码

                            01h,非法的功能(文件共享)

                            04h,无可用的句柄

                            05h,访问被禁止

                            06h,无效句柄

                            0Dh,非法数据

                            0Fh,无效驱动器

注释: IOCTL功能是能在DOS使用的最为复杂的功能之一。该功能拥有18

    个独立的子功能。表16.9粗略地介绍了这18个子功能,以及正式采用这些子

    功能的DOS版本。 AL寄存器传送出来的信息含义与所定址的特定设备驱动

    程序有关。

                          表16.9设备功能代码

AL                      含    义                            DOS版本

00h                   获取设备信息                                2.0

01h                   设置设备信息                                2.0

02h                   字符设备读                                  2.0

532页

AL                      含    义                            DOS版本

    03h                 字符设备写                                    2.0

    04h                 块设备读                                      2.0

    05h                 块设备写                                      2.0

    06h                 获取输入状态                                  2.0

    07h                 获取输出状态                                  2.0

    08h                 块设备可否改变?                              3.0

    09h                 块设备是本地的还是远程的                      3.1

    0Ah                 句柄是本地的还是远程的                        3.1

   0Bh                  设置共享重试计数                              3.0

    0Ch                 用于句柄的通用I/O控制                        3.2

    0Dh                 用于块设备的通用I/O控制                       3.2

0Eh                     获取逻辑驱动器映象                            3.2

    0Fh                 设置逻辑驱动器映象                            3.2

    10h                 询问IOCTL句柄                                 5.0

    11h                 询问IOCTL设备                                 5.0

      IOCTL功能是一个广义的设备一驱动程序接口程序,其目的不是传送数

据,而是与驱动程序通信,并告诉驱动程序如何工作。

系统

Int 21h           功能44h   子功能00h                   版本2

                  获取设备信息

    获取句柄引用的设备或文件的有关信息

    调用寄存器: AH          44h

                      AL              00h

                      BX              句柄

    返回寄存器:进位标志清除表示成功

                DX          设备信息(参见表16.10)

                进位标志置位表示出错

                AX          出错码

                            01h,非法功能

                            05h,访问被禁止

                            06h,无效句柄

    注释: DX寄存器返回系统内通过BX寄存器中的文件句柄来访问的字符设

    备或文件的编码信息。表16.10列出了这些代码及各自的含义。在这里,句柄

    必须引用某个打开的文件或字符设备。

533页

    表16. 10设备信息代码

              位设置

                                      含    义

FEDCBA9876543210

              字符设备

. . . . . . . . . . . . . . . 1     标准输入设备

. . . . . . . . . . . . . . 1.     标准输出设备

. . . . . . . . . . . . . 1. .       NUL设备

. . . . . . . . . . . . 1. . .      时钟设备

. . . . . . . . . . . 0. . . .      设备不支持Int 28h

. . . . . . . . . . . 1. . . .      设备支持Int 28h

. . . . . . . . . . 0. . . . .      修改的模式

. . . . . . . . . . 1. . . . .      原始(二进制)模式

. . . . . . . . . 0. . . . . .      输入文件的终点

. . . . . . . . . 1. . . . . .      未到达输入文件的终点

. . . . . . . . 1. . . . . . .      字符设备

. . x x x x x x . . . . . . . .     保留

. 1. . . . . . . . . . . . . .      设置能够处理通过子功能02h和03h而传送的

                                    控制字符串,只能读取该位而不能设置它

x. . . . . . . . . . . . . . .      保留

          块设备(磁盘文件)

. . . . . . . . . . x x x x x x 块设备(0=A、1=B等等分别代表第1个至第n

                                    个块驱动程序)

. . . . . . . . . 0. . . . . .      文件已被写入

. . . . . . . . . 1. . . . . .      文件尚未被写入

. . . . . . . . 0. . . . . . .      块设备(磁盘文件)

. . x x x x x x . . . . . . . .     保留;在调用此功能时必须将其置为0

. 1. . . . . . . . . . . . . .      设备能够处理通过于功能02h和03h传送的控

                                    制字符串。但只能读取该位而不能设置它

x. . . . . . . . . . . . . . .      保留

      用于字符设备的位5是一个极其有用的信息位。当UNIX程序员们在处

理终端设备时,他们非常熟悉下面的两个术语,即:“修改的(Cooked)模式”和

“原始模式”。在COS中,修改的(cooked)模式意味着处理Ctrl-C、Ctrl-P、Ctrl-

Q、Ctrl-S和Ctrl-Z,以及在检测到回车符而不是指定数目的字符时所终止的

输入。修改的模式是一种全编辑输入模式,许多参考手册将它描述为唯一的控

制台输入模式。

      在原始模式中,所应用的I/O系统驱动程序忽略了这些字符的特殊含义,

并且一直等到收到了全部规定的字节数据时才从读操作中返回。无需经过I/

O系统或DOS的解释,驱动程序可将所有接收到的字节直接传送给应用程

序。类似的区别也存在于输出进程上(标记字符的展开、换行前回车符的自动

出现、以及等等)。

 

534页

      BX寄存器中的句柄必须访问打开的文件或设备。如果不这样的话,该功

能就会返回错误代码06h(无效的句柄)。

      在返回时,DX寄存器中的位8-15分别对应于设备驱动程序属性字节中

的相同位。(关于属性字和驱动程序标题的具体情况可参见第12章“设备驱动

程序”)。

系统

Int 21h             功能44h   子功能01h                     版本2

                    设置设备信息

    这一子功能只用于字符设备,其作用是允许设置设备信息代码

    调用寄存器: AH          44h

                      AL              01h

                      BX              句柄

                      DX              设备数据字

    返回寄存器:进位标志清除表示成功

                进位标志置位表示出错

                AX          出错码

                            01h,非法功能

                            05h,访问被禁止

                            06h,无效句柄

                            0Dh,无效数据

    注释:子功能01h仅允许为字符设备设置一定部分的设备数据字。在这种调

    用中,唯一经常被修改的位是位5。(关于原始模式和修改模式的解释,可参见

    子功能00h的介绍)。

        如果DH寄存器不为零,该功能就会返回错误代码01h(非法功能)。这种

    子功能也要求句柄引用打开设备。如果句柄为文件,那么系统就不会更新任何

    信息。表16.11详细介绍了设备数据字(DX寄存器)。

                          表16.11设备数据字

              位设置

                                          含    义

FEDCBA9876543210

. . . . . . . . . . . . . . . 1         标准输入设备

. . . . . . . . . . . . . . 1.         标准输出设备

. . . . . . . . . . . . . 1. .           NUL设备

. . . . . . . . . . . . 1. . .          时钟设备

. . . . . . . . . . . 1. . . .          设备支持Int 28h

. . . . . . . . . . 0. . . . .          修改的模式

. . . . . . . . . . 1. . . . .          原始(二进制)模式

535页

              位设置

                                            含    义

    FEDCBA9876543210

. . . . . . . . . 0. . . . . .        输入文件的末尾

. . . . . . . . 1. . . . . . .        字符设备

x x x x x x x x . . . . . . . .       保留

系统

Int 21h           功能44h     子功能02h                     版本2

                  设备IOCTL读

从驱动程序中获取控制字符串信息以供调用程序使用

调用寄存器: AH            44h

              AL         02h

              BX          句柄

               CX         要获取的字节数

              DS:DX     指向数据缓冲区的指针

返回寄存器:进位标志清除表示成功

              AX            已传送的字节数

              进位标志置位表示出错

              AX          出错码

                          01h,非法功能

                          05h,访问被禁止

                          06h,无效句柄

                          0Dh,无效的数据

注释:可通过控制字符串把驱动程序的任意信息传送给调用程序。在这里,任

意信息指的是驱动程序中可用来支持系统的各种信息;并且这些信息不存在

任何标准的格式和内容。驱动程序响应请求的方式是让请求直接到达驱动程

序上。第12章“设备驱动程序”详细介绍了控制字符串的情况,对此有疑问的

读者可以参看第12章的内容。

      子功能00h的位0Eh表明驱动程序是提供还是响应控制字符串。

系统

Int 21h             功能44h   子功能03h                     版本2

                    设备IOCTL写

把控制字符串的信息传送给驱动程序

    调用寄存器: AH          44h

536页

     AL           03h

                    BX            句柄

                    CX            要传送的字节数

                    DS:DX       指向数据缓冲区的指针 

        返回寄存器:进位标志清除表示成功

                    AX            已传送的字节数

                    进位标志置位表示出错

                    AX            出错码

                                  01h,非法功能

                                  05h,访问被禁止

                                  06h,无效句柄

                                  0Dh,无效的数据

        注释:有关驱动程序的任意信息都可放入一个控制串中而传递给驱动程序。

        这种信息可以是驱动程序所支持的任何信息;对此信息或消息的内容的格式,

        无任何标准可言。驱动程序响应请求的方式同样完全依赖于该驱动程序本身。

        第12章“设备驱动程序更详细地讨论了控制串的内容。本子功能经常用于向

        驱动程序传递配置信息,如波特率、字长度等。

            子功能00h的位0Eh能指明驱动程序能否提供或响应控制串。

系统

Int 21h             功能44h     子功能04h                     版本2

                    块驱动程序IOCTL读

从一个块驱动程序(磁盘类型)中读取控制信息

调用寄存器: AH              44h

              AL           04h

              BL            驱动号

              CX            要获取的字节数

              DS:DX       指向数据缓冲区的指针

返回寄存器:进位标志清除表示成功

              AX            传送的字节数

              进位标志置位表示出错

              AX            出错码

                            01h,无效功能

                            05h,访问被禁止

                            06h,无效句柄

                            0Dh,无效数据

537页

注释:子功能04h能通过控制字符串从块驱动程序中写给关于块驱动程序的

    任何信息。这种信息既可以是状态信息,也可以是驱动程序中可用来支持系统

    的各种信息。对这些信息而言不存在任何格式或内容上的标准。

      驱动程序响应请求的方式是让请求直接到达该驱动程序上。第12章“设

备驱动程序”中详细介绍了控制字符串的情况,这里就不再复述。在这一子功

    能的日常应用中,还涉及到块设备操作的准备工作。如果是为了CD-ROM驱

    动器、磁带驱动器之类的设备而写驱动程序,那么系统有可能会询问这类设

备。

      子功能00h中的位0Eh表明驱动程序功能是提供控制字符串还是响应

    控制字符串。这一子功能不要求块设备驱动程序的支持。但是,如果所调用的

    驱动程序不支持它,系统就会返回错误代码01h(非法功能)。

系统

Int 21h           功能44h     子功能05h                   版本2

                  块驱动程序IOCTL写

把控制信息传送给块设备(磁盘类型)

调用寄存器: AH            44h

              AL         05h

              BL          驱动器号

              CX          要传送的字节数

              DS:DX    指向数据缓冲区的指针

返回寄存器:进位标志清除表示成功

              AX          已传送的字节数

              进位标志置位表示出错

              AX          出错码

                           01h,非法功能

                          05h,访问被禁止

                          06h,无效句柄

                          0Dh,无效数据

注释:子功能05h通过控制字符串把关于块驱动程序的任何信息传递给该驱

动程序。这些信息中可以包括命令或驱动程序中可写来支持系统的各种信息。

对这些信息而言,不存在任何格式或内容上的标准。

      驱动程序响应请求的方式是让请求直接到达驱动程序上。关于控制字符

串的详细情况可参见第12章“设备驱动程序”,这里就不作介绍。此外,这一子

功能在实际应用中还起着非I/O设备功能的作用,如磁带倒带和磁盘弹出等。

      子功能00h中的位0Eh表明驱动程序是提供控制字符串还是应答控制

字符串。这一子功能不要求块设备驱动程序的支持,但是,若所调用的驱动程

 

538页

序不支持该子功能,系统就会返回出错码01h(非法功能)。

系统

Int 21h             功能44h   子功能06h                     版本2

                    获取输入状态

返回输入操作过程中使用的设备或文件的状态

调用寄存器: AH             44h

              AL           06h

              BX            句柄

返回寄存器:进位标志清除表示成功

              AX            输入状态码(参见表16.12)

              进位标志置位表示出错

              AX            出错码

                            01h,非法功能

                         05h,访问被禁止

                            06h,无效句柄

注释:通过这一子功能就能知道某个设备或文件是否作好了迎接输入操作的

准备。如果文件没有被功能42h定位,则可以检查文件是否处于EOF,同时,

还可检查字符设备是否作好了操作的准备。表16.12列出了输入状态代码(寄

存器AH),并对代码的含义作了解释。

              表16.12用于功能44h,子功能06h的输入状态代码

代码                  文件                                设备

00h                   位于EOF                             未准备好

FFh                   不位于EOF                           准备好

(说明:如果用Int 21h,功能42h把文件定位在EOF上,该文件就不会返回EOF)。

系统

Int 21h           功能44h     子功能07h                     版本2

                  获取输出状态

返回用于输出的文件或设备的状态

调用寄存器: AH              44h

              AL           07h

              BX            句柄

返回寄存器:进位标志清除表示成功

              AL            输出状态代码(参见表16.13)

              进位标志置位表示出错

539页

                AX            出错码

                              01h,非法功能

                              05h,访问被禁止

                              06h,无效句柄

    注释:通过这一子功能就可以知道某个设备或文件是否作好迎接输出操作的

    准备。正如下表所示,文件总是返回“ready”;而字符设备却不是这样。

                  表16.13用于功能44h,子功能07h的输入状态代码

代码                  文件                                设备

00h                   位于EOF                               未作好准备

FFh                   不位于EOF                             已作好准备

系统

Int 21h           功能44h     子功能08h                     版本2

                  块设备可否移动?

用于确定某个块设备是否可移动

调用寄存器: AH              44h

              AL           08h

              BL            驱动器号

返回寄存器:进位标志清除表示成功

              AX            00h,可移动的媒体

                            01h,非可移动的媒体

              进位标志置位表示出错

              AX            出错码

                            01h,非法功能

                            0Fh,无效驱动器

注释:通过一子功能,那些需要在特定设备上定位数据文件、或加上覆盖物的

应用程序就能确定该设备是否要移动。如果未能把所期望的文件定位在特定

的设备上,并且该设备是可移动的,那么程序就会提示用户插入正确的磁盘,

以便继续操作。

      设备驱动程序属性字中的位0Bh表明了驱动程序能否支持该功能。有些

驱动程序的确不能提供支持。在这种时候,子功能08h就会返回出错代码为

01h。

系统

Int 21h             功能44h     子功能09h                       版本2

                    块设备是本地的还是远程的?

确定块设备是本地的还是远程的

540页

    调用寄存器: AH           44h

                  AL          09h

                  BL          驱动器号

    返回寄存器:进位标志清除表示成功

                  DX          设备属性字

                              位12=1,设备是远程的

                              位12=0,设备是本地的

                  进位标志置位表示出错

                  AX          出错代码

                              01h,非法功能

                              0Fh,无效驱动器

注释:如果网络未被启动,则这一子功能就返回出错代码01h,表明所用的功

能无效。

      在编程过程中,最好不要使用这种功能。因为无论采用何种方法来编写程

序,所编写出来的程序都应该与网络上任何一个特殊设备的位置无关。但是,

即使使用这种功能,一些未公开的功能还是能正确地操作,它们只与本地文件

有关,而不能通过远程文件来使用它们;如果在程序中必须要用于这样一种未

公开的功能,那么在使用子功能09h时就会避免出现某些错误。

      如果DX的位12为0,则表明驱动器是本地的,同时DX的其他各位还分

别表示着如下含义:

      位1       1= 驱动器使用32位扇区定址

      位6       1= 驱动器支持功能44h,子功能0Dh、0Eh和0Fh

      位7       1= 驱动器支持功能44h,子功能11h

      位9       1= 驱动器是本地的,但被网络中的其它计算机共享

      位11       1= 驱动器支持功能44h,子功能08h

      位13       1= 在FAT中,驱动器要求介质描述符

      位14      1= 驱动器支持功能44h,子功能04h和05h

      位15       1= 子功能驱动器(即通过SUBST命令设置的驱动器)

      所有的其他的位都为0。

系统

Int 21h           功能44h   子功能0Ah                   版本2

                  句柄是本地的还是远程的?

确定句柄是本地的还是远程的

调用寄存器: AH           44h

              AL           0Ah

              BX            句柄

返回寄存器:进位标志清除表示成功

              DX            设备属性字

                            位15=1,句柄是远程的

541页

                              位15=0,句柄是本地的

                  进位标志置位表示出错

                  AX          出错码

                              01h,非法功能

                              06h,无效句柄

      注释:如果未能启动网络,这一子功能就会返回出错代码01h,表明所使用的

      功能无效。

        在编程过程中,最好不要使用这种功能。因为无论采用何种方法来编写程

    序,所编写出来的程序都应该与网络上任何一个特殊设备的位置无关。不过,

      即使使用这一子功能,一些未公开的功能还是能正确地操作,它们只与本地句

      柄发生作用,而不能通过远程句柄来使用它们;如果在程序中必须要用于这种

      未公开的功能,那么在使用子功能0Ah时就会避免出现一些错误。

        DX中的位7清除,表示句柄已标识了文件,而且DX中的其他各位还分

      别有如下含义:

        位0-5        驱动程序号(0=A、1=B等等)

          位6       1= 文件未被写入

          位12       1= 无继承

          位14       1= 在关闭时未设置日期/时间

          其余所有的位都为0。

          如果DX的位7置位,表明句柄为一设备句柄,同时,DX中的其它各位分

      别表示着如下含义:

          位0      控制台输入设备

          位1       1= 控制台输出设备

          位2       1= 空设备

          位3       1= 时钟设备

          位4       1= 特殊设备

        位5       1= 二进制模式

                    0= ASCII码

          位6       1= 如果设备被读,则返回EOF

          位11       1= 网络假脱机

        位12       1= 未继承

          位13       1= 命名管道

          其余各位均为0。

系统

Int 21h           功能44h   子功能0Bh                 版本2

                  设置共享重试计数

    可改变用于在网络间进行文件共享的重试参数

 

542页

    调用寄存器: AH          44h

                AL         0Bh

                CX          重试间的暂停

                DX          重试次数

    返回寄存器:进位标志清除表示成功

                进位标志置位表示出错

                AX          出错码

                            01h,无效功能

    注释:当在一个网络上使用多台PC机时,重试参数便受到文件锁定机制的

    控制。该机制假定文件锁定是暂时的,并且在经过短暂的更新后会得到清除。

因此,在进行第一次访问时,文件如果是锁着时,那么这样一种内存的机制就

    会自动地重试以建立起对该文件的再次访问。

      有两种参数与系统有关,这两种参数分别是重试计数和重试间的暂停。不

    同的CPU以及不同的时钟速度都对这种暂停的长度有着重大的影响。

      通过给定紧密计时循环将被执行的次数CX寄存器就能控制暂停。由于

    无论什么时候调用计时循环,它都会重复循环65536次。因此,可以清楚地看

    出,在计算机未报告出错之前,进行访问的次数就是重试计数。通过缺省,

    PAUSE=1,并且RETRY=3。

      可用这些参数来做微调系统,以使文件共享方面的问题减少到最小。如果

    希望较长的文件锁定时间,那么在对该文件进行再一次访问时,可以拒绝暂停

    时间。但是,如果改变了任何一个缺省值,那么通过恢复该缺省来防止对其他

    程序的影响就不会有很好的效果。

系统

Int 21h           功能44h   子功能0Ch                 版本3.2

                  面向句柄的通用I/O控制

在DOS版本3.2中,设置或获取用于字符类设备的重复计数。在DOS的版本

3.3以及更高的版本中,该功能方式实现代码页转换。在DOS版本5.0中,该

功能还能获取和设置显示方式。

调用寄存器: AH          44h

                    AL             0Ch

                    BX              句柄

                    CH              分类代码(设备类型)

                    DOS版本3.2

                                    05h,打印机

                    DOS版本3.3以及更高的版本

                                    00h,未知

                                    01h,COMx

                                    03h,CON

543页

                                      05h,LPTx

                    CL                次级功能代码

                    DOS版本3、2以及更高的版本

                                      45h,设置重复计数

                                      65h,获取重复计数

                    DOS版本3.3以及更高的版本

                                      4Ah,选择

                                      4Ch,准备启动

                                      4Dh,准备终止

                                      6Ah,询问选择

                                      6Bh,询问准备列表

                    DOS版本5.0

                                      5Fh,设置显示模式

                                      7Fh,获取显示模式

                    DS:DX           指向重复计数字的指针(次级代码45h和65h)

                                      指向参数块的指针(次级代码、4Ah、4Ch、4Dh、

                                      5Fh、6Ah、4Bh和7Fh)

返回寄存器:进位标志清除表示成功

              AX            已传送的字节数

              进位标志置位表示出错

              AX          出错码

                          01h,无效功能

注释:重复计数是指某个操作在终止前所进行的次数。在DOS版本3.2中,

唯一允许使用的是分类代码05h(打印机)。

      在DOS版本3.3以及更高的版本中,该子功能的用途已发生了改变,在

这些版本中,它的作用是处理用于设备的代码页转换。其下属的次级功能如

下:

      ·准备启动(4Ch)来通知驱动程序作好通过子功能03h装载代码页字体

        的准备。一种较特殊的启动操作是“更新”操作,这种操作是通过把所

        有代码ID号设置为FFFFh而实现的。

      ·准备终止(4Dh),通知驱动程序,代码页字体装载工作已完成。

      ·选择代码页(4Ah),选择要使用的代码页。

      ·设置显示模式(5Fh),设置供设备使用的显示模式。

      ·询问已选择的代码页(6Ah),从设备中确定出代码页的状态。

      ·询问准备列表(6Bh,确定设备上的代码页列表。

      ·获取显示模式(7Fh),获取设备所使用的显示模式。

      表16.14给出了DS:DX所指的参数块的定义。

 

544页

    表16.14参数块

字节                              含    义

    次级功能4Ah、4Dh、6Ah

   0-1                              跟随数据的长度

    2-3                              代码页ID号

    次级功能4Ch

   0-1                              标志

    2-3                              参数块(位于该点之后)的长度

   4-5                             代码页的页数

    ·                              代码页标志

    次级功能6Ah

   0-1                              参数块(位于该点之后)的长度

    23                              硬件代码页数

    ·                              硬件代码页标志

    n-n+1                         已准备的代码页数

    ·                              已准备的代码页标志

    次级功能5Fh、7Fh

    0                              信息层(必须为零)

    1                               保留

    23                              参数块(位于该点之后)的长度

   4-5                             控制标志

                                    0=亮度关

                                    1=亮度开

    6                               显示模式

                                    1= 文本模式

                                    2= 图形模式

    7                               保留

    8-9                              颜色数目

    0A-0B                           按象素计算的屏幕宽度(仅适用于图形模式)

    0C-0D                          按象素计算的屏幕长度(仅适用于图形模式)

    0E-0F                            列

    10-11                            行

545页

系统

Int 21h           功能44h 子功能0Dh                 版本2

                  用于块设备的通用I/O控制

共有六种输入/输出功能可用于在块设备上处理特殊功能

调用寄存器: AH          44h

                  AL             0Dh

                  BL              驱动器

                  CH              分类代码

                                  08h,磁盘驱动器

                  CL              次级功能代码

                                  40h,为块设备设置参数

                                  41h,写逻辑驱动器上的磁道

                                  42h,格式化并检验逻辑驱动器上的磁道

                                  46h,设置介质ID号

                                  60h,获取用于块设备的参数

                                  61h,读逻辑设备上的磁道

                                  62h,检验逻辑驱动器上的磁道

                                  66h,获取介质ID号

                                  68h,读出介质类型

                  DS:DX         指向参数的指针

返回寄存器:进位标志清除表示成功

              进位标志置位表示出错

              AX          出错码

                          01h,非法功能

                          02h,无效驱动器

注释:子功能0Dh是用来扩展该功能的性能,以便控制块设备。许多原始操

作都可通过这种IOCTL调用并按照一种与设备无关的方式来进行控制。这一

子功能对其下属的每一项次级功能都进行单独的检验。

      对于任何一个指定的驱动器来说,必须首先调用次级功能40h(设置设备

参数),然后才能调用其他的次级功能。

          次级功能40h:设置设备参数

      次级功能40h用一个参数块来反映块设置设备的整个布局,其中包括物

理字符、媒体类型等等。

546页

    参数块布局

字节偏移值                            含    义

      00h                               特殊的功能代码

      01h                               设备类型代码

      02-03h                             设备属性代码

      04-05h                             柱面数

      06h                               介质类型代码

      07-25h                           设备BPB

      26h-?                             磁道布局表

特殊的功能代码

                位

                                          含    义

        76543210

. . . . . . . 0               DPB项是新的BPB

. . . . . . . 1               使用当前BPB

. . . . . . 0.               使用参数块中的全部字段

. . . . . . 1.               只使用磁道布局字段

. . . . . 0. .                磁道中的各个扇区可能有不同的大小

. . . . . 1. .                磁道中的各个扇区大小都相同

00000. . .                    保留

    设备类型代码

      代码                      含    义

00h                    320/360K,5.25英寸的磁盘

01h                    1.2M,5.25英寸的磁盘

02h                    720K,3.5英寸的磁盘

03h                   单密度,8英寸的磁盘

04h                   双密度,8英寸的磁盘

05h                   固定磁盘

06h                   磁带驱动器

07h                   其他块设备

设备属性代码

          位

                                    含    义

76543210

    . . . . . . . 0             可移动的存储器

    . . . . . . . 1             不可移动的存储器

    . . . . . . 0.             设备不指示更改行状态

    . . . . . . 1.             设备指示更改行状态

    x x x x x x . .             保留

547页

介质类型代码

代码                                含    义

    00h                                 1.2M,5.25英寸的磁盘

    01h                                  320/360K,5.25英寸的磁盘

BIOS参数块(BPB)布局

偏移值(字节)          字段(长度)            含    义

00h                    Word               每扇区的字节数

02h                    Byte               每簇的扇区数

03h                    Word               从扇区0开始的保留扇区数

05h                    byte                FAT的数目

06h                    Word               最大的根目录项数

08h                    Word               总扇区数

0Ah                    byte               介质描述符

0Bh                    Word               每FAT的扇区数

0Dh                    Word               每磁道的扇区数

0Fh                    Word               磁头数

11h                    Double word        隐藏扇区数

15h                    11 bytes           保留

    磁道布局表

长度                                    含    义

    word                            磁道中的扇区数

    Word                            磁道中的第一个扇区号

    Word                            磁道中的第一个扇区的大小

    word                            磁道中最后一个扇区号

    word                            磁道中最后一个扇区的大小

          次级功能41h:写磁道

      写磁道功能允许使用用于描述磁道的全部重要参数(磁头、柱面、扇区、扇

区数和数据的位置)说明。为了便于计数,扇区数和柱面数都从0开始计算。

                                参数块

偏移值                              含    义

00h                                 特殊功能=0

01h-02h                            要使用的磁头号

03h-04h                            要使用的磁盘柱面号

05h-06h                            第一个使用的扇区

07h-08h                            要传送的扇区数

09h-0Ch                            指向数据传送缓冲区的指针

548页

          次级功能42h:格式化并检验磁道

      该功能格式化和检验磁道上的磁道,但在使用该功能时,必须指定要使用

的柱面和磁头,余下来指定的内容统统由驱动程序来处理。

                          参数块——格式化磁道

偏移值                                含    义

00h                             特殊功能=0

01h-02h                        要使用的磁头号

03h-04h                        要使用的柱面号

参数块——检验格式化状态

偏移值                              含    义

    00h                               特殊功能=1

    01h-02h                          要使用的磁头号

    03h-04h                          要使用的柱面号

      说明:如果对特殊功能字段进行状态检查,那么返回的值有如下几种可

能:

          0= 受ROM BIOS支持,允许磁头/柱面

          1= ROM BIOS不支持

          2= 不允许已指定的磁头/柱面

          3= 驱动器为空

          次级功能46h:设置介质ID号

      这一功能设置指定驱动器的顺序号、卷标和文件系统类型。

                              参数块

偏移值                                含    义

    00-01h                             信息层

    02-05h                           顺序号

   06-10h                            ASCII卷标

    11-18h                           文件系统类型

    “FAT12”                         12位的FAT

    “FAT16”                         16位的FAT

          次级功能60h:获取参数

      这一功能是次级功能40h的扩展。它使用与次级功能40h相同的参数块

格式来从驱动程序中获取有关设备的信息。

          次级功能61h:读磁道

      该功能把磁道读进参数块中的内存缓冲区。然后,通过写磁道次级功能,

就可把这种位置信息传送给驱动程序。

549页

参数块

偏移值                              含    义

    00h                             特殊功能=0

    01-02h                         要使用的磁头号

    03-04h                           要使用的磁盘柱面号

    05-06h                         第一个使用的扇区

    07-08h                         要传送的扇区数

    09-0Ch                          指向数据传送级冲器的指针

        次级功能62h:检验磁盘

    该功能实现次级功能62h中格式化/检验磁道操作的磁道检验操作部分。

                            参数块

    偏移值                            含    义

00h                                特殊功能=0

01h-02h                          要使用的磁头号

03h-04h                          要使用的磁盘柱面号

      次级功能66h:获取介质ID号

该功能获取指定驱动器的顺序号、卷标和文件系统类型。

                          参数块

偏移值                              含    义

    00-01h                           信息层

    02-05h                         顺序号

    06-10h                          ASCII卷标

    11-18h                         文件系统类型

    “FAT12”                       12位的FAT

    “FAT16”                       16位的FAT

        次级功能68h:读出介质类型

    该功能返回指定驱动器的介质类型

                          参数块

偏移值                              含    义

    00h                             缺省标志

                                    0=不是缺省类型的介质

                                    1=缺省类型的介质

    01h                             介质类型

                                    2=720K磁盘

                                    7=1.44M磁盘

                                    9=2. 88M磁盘

550页

系统

Int 21h           功能44h     子功能0Eh                   版本3.2

                  获取逻辑驱动器映象

确定是把1个还是多个逻辑驱动器指定给某个设备

调用寄存器: AH              44h

              AL           0Eh

              BL            驱动器

返回寄存器:进位标志清除表示成功

              AL            驱动器号

                            0= 只指定一个逻辑驱动器号

                            1=A,2=B,依此类推

              进位标志置位表示出错

              AX            错误代码

                            01h,无效功能

                            05h,访问被禁止

                            0Fh,无效驱动器

注释:由调用返回的驱动器号将通知用户:如果用于设备的逻辑驱动器标志

不止一个,那么应使用最后一个驱动器标志来访问该驱动器。

系统

Int 21h             功能44h     子功能0Fh                     版本3.2

                    设置逻辑驱动器映象

设置用于访问下一个设备的逻辑驱动器名

调用寄存器: AH             44h

                AL         0Fh

              BL          驱动器号

返回寄存器:进位标志清除表示成功

                AL          驱动器号

                            0=只指定一个逻辑驱动器号

                            1=A,2=B,依此类推

                进位标志置位表示出错

                AX             出错代码

                            01h,无效功能

                            05h,访问被禁止

                           0Fh,无效驱动器

551页

注释:在两个磁盘间进行文件复制时,两个磁盘可分别使用不同的逻辑设备,

不过,两者都得使用同一个物理设备。当在对某个设备进行I/O操作时,如果

这个设备当前不在驱动器内,那么系统会提示改变磁盘。该功能允许在没有系

统提示的前提下强制进行磁盘切换。

      该功能通过设置下一次可能调用的驱动器字母来引用设备。这样,DOS

就不会提示用户去"Insert Disk"。同时,子功能0Eh确定用来访问该设备的最

终逻辑驱动器的名字。

系统

Int 21h           功能44h     子功能10h                   版本5

                  询问IOCTL句柄

确定由设备句柄指定的设备是否支持特定的IOCTL功能

调用寄存器: AH            44h

                    AL              10h

                    BX              句柄

                  CH                分类代码

                    CL              功能代码

                    DS:DX        指向参数块的指针

返回寄存器:        进位标志清除表示成功

                    AX              0

                    进位标志置位表示出错

                    AX               01h,不支持所用的功能

                                    05h,访问被禁止

注释:设置参数块的目的是为了供通用的IOCTL调用使用。如果设备弄不清

是否支持Qurey IOCTL,那么可用该功能来确定驱动程序是否支持指定的通

用IOCTL调用。最典型的情况是,在发出通用IOCTL调用之前,应用程序会

首先询问驱动程序。

系统

Int 21h           功能44h   子功能11h                   版本5

                  询问IOCTL设备

确定句柄指定的设备是否支持特定的IOCTL功能

调用寄存器: AH           44h

                  AL               11h

                  BX                句柄

                  CH                分类代码

552页

                  CL          功能代码

                  DS:DX     指向参数块的指针

    返回寄存器:进位标志清除表示成功

                  AX          0

                  进位标志置位表示出错

                  AX           01h,不支持所用的功能

                              05h,访问被禁止

                              0Fh,无效驱动器

    注释:设置参数块的目的是为了供通用的IOCTL调用使用。如果设备对支持

    Qurey IOCTL有疑问,那么就可用该功能来确定驱动程序是否支持指定的通

    用IOCTL调用。典型的情况下,应用程序会在发出通用IOCTL调用之前,首

    先询问驱动程序。

        DOS 5.0支持如下几种功能:

            40h         设置设备参数

            41h         写逻辑驱动器上的磁道

            42h         格式化逻辑驱动器上的磁道

            46h         设置介质ID号

            60h         获取设备参数

            61h         读逻辑驱动器上的磁盘

            62h         检验逻辑驱动器上的磁道

            66h         获取介质ID号

            68h         读取介质类型

磁盘

Int 21h           功能45h                                 版本2

                  复制句柄

    提供一个新句柄,用于已经被打开的设备或文件

    调用寄存器: AH          45h

                BX          文件句柄

    返回寄存器:进位标志清除表示成功

                AX          新句柄

                进位标志置位表示出错

                AX          错误代码

                            04h,无可用的句柄

                            06h,无效句柄

    注释:复制文件句柄,以便提供另一个用于同一文件的句柄。这两个文件指针

 

553页

通常汇聚在一起。如果移动一个文件的文件指针,那么用于其它文件的文件指

针也会随之移动。

      该功能最常见的用途是强制更新文件的目录项,且不会招致多余的文件

打开或关闭操作。在早于3.3的DOS版本中,这是唯一的一种强制更新文件

目录项的方法。DOS版本3.3采用了新的功能68h,这种功能不仅能做到同样

的事情,而且使用起来更加容易。

磁盘

Int 21h           功能46h                                 版本2

                  强制复制句柄

在相同的位置上,产生两个文件句柄引用同一个打开的文件。

调用寄存器: AH              46h

                BX          第一个文件句柄

                CX          第二个文件句柄

返回寄存器:进位标志清除表示成功

                AX          新句柄

                进位标志置位表示出错

                AX          错误代码

                            04h,无可用的句柄

                            06h,无效句柄

注释:该功能的结果与功能45h类似;都使用两个文件句柄来引用同一个文

件,并且这两个句柄同时移动。该功能最为重要的用途是用于设备重定向操

作。通过如下步骤,就能够从另一个程序的内部来控制设备重定向进程,并接

着把设备返回到常规状态。

      1.使用功能45h来复制要对其进行重定向的句柄。保存新的句柄,以便

          用于随后的恢复进程。

      2.使用功能46h来进行重定向,具体方法是将要“对其进行重定向”的两

        个句柄(复制后)分别放入CX和BX。

      当要返回到常规状态时,只需将重定向后的句柄放入CX,将功能45h返

回的复制句柄放入BX寄存器,即可再次调用功能46h来实现这一目的。

      在调用寄存器内,如果CX中的句柄引用的是一个打开文件,那么在该功

能启动之前,首先应关闭这个文件。

磁盘

Int 21h           功能47h                                 版本2

                  获取当前目录

554页

    返回当前目录的完整路径名的ASCIIZ字符串,其中不包括驱动器名和反斜

    杠(\)。

    调用寄存器: AH          47h

                DL          驱动器代码(0=缺省,1=A,如此类推)

               DS:SI        指向5个字节的暂时缓冲区的指针

    返回寄存器:进位标志清除表示成功

                DS:SI      未改变,缓冲区中含有当前目录路径的

                            ASCIIZ串

                进位标志置位表示出错

                AX          出错代码

                             0Fh,无效驱动器

    注释:该功能返回当前目录的路径名,其中不包括驱动器标志符或反斜杠

    (\)。由于是在调用该功能时设置了驱动器代码,因而缺少驱动器标志符和斜

    杠是正确的。(如果想用该功能返回的字符构成文件名,那么就必须在文件名

    中加上驱动器和初始斜杠)。如果所使用的目录为根目录,则该功能返回的字

    符串产NUL(第一个字节0)。

        若在改变目录之前使用这一功能,许多程序就能从中获益,这样,在程序

    完成时,用户就能返回到初始目录。但程序员们必须小心,因为无效驱动器代

    码会导致失败。要设置当前目录,最好用功能3Bh。

系统

Int 21h             功能48h                                     版本2

                    分配内存

分配供程序使用的内存块,并返回一个指向该内存块头部的指针。

调用寄存器: AH              48h

              BX            所需的节数(每节16字节)

返回寄存器:进位标志清除表示成功

              AX            已分配的块的起始段

              进位标志置位表示出错

              AX            出错代码

                            07h,内存控制块被破坏

                            08h,内存不够

              BX            如果该功能失败,则为最大可用块的大小

注释:返回的指针是块基地址(基地址为AX:0000h)中的段地址。由于总是

把所有的内存都分配给COM程序,因而在从COM程序中调用该功能时,该

功能都会失败,除非在进入COM程序时,该程序已释放出了内存。(详细情况

555页

请见第3章“动态的DOS”和第10章“程序和内存管理”。)

      在多任务环境中,进程所见到的内存顶部有可能不是实际的内存顶部。

DESQview和Windows之类的程序只分配给每个程序与程序信息文件中所

要求的空间。

      如果获取空间的调用失败,该功能就会返回最大可用内存块的大小。这样

的话,再一次发出请求超过这个内存空间的调用就能成功。EXEC装入程序功

能就是使用这种技术把所有可用的RAM分配给COM程序的。首先,这种功

能把FFFFh装入BX,这样就能请求到1048560个字节的RAM(大于所有可

用的RAM)。由于其结果是返回出错代码8,因而没有实现任何检查。对功能

48h的调用应重复一次,第一次调用通过BX返回实际可用的内存量,第二次

调用才分配所需数量的内存。

      如果希望弄清楚RAM的数量,也可以在你自己的程序中使用同样的技

术(因为可用的RAM数量对任何程序不是保留的)。如果把BX设置为

FFFFh来使用功能48h,那么BX返回的值就是可用的内存块数。

系统

Int 21h           功能49h                               版本2

                  释放内存

把内存块释放到DOS管理的内存池中(使得内存可供其他程序使用)。

调用寄存器: AH            49h

              ES          要释放的块的段地址

返回寄存器:进位标志清除表示成功

              进位标志置位表示出错

              AX          出错代码

                          07h,内存控制块被破坏

                          09h,无效的内存块地址

注释:该功能假定要释放的内存块是功能48h所请求的内存块。如果内存块

不是功能48h所请求的,那么该功能就会失败(如果幸运的话),或者它会导致

程序在释放内存的过程中,或在其它常驻内存的程序中出现不可思议的错误。

之所以会出现这类问题是因为当系统通知程序会释放内存时,程序就希望用

给定的地址引用指定的内存块,并把这一过程列为总内存分配方案的一部分。

关于内存管理的具体细节可参见第10章“内存管理”。

系统

Int 21h           功能4Ah                               版本2

                  修改内存分配

556页

    扩展或缩小先前用功能48h分配的内存块。

    调用寄存器: AH          4Ah

                BX          按节计算的新请求块的大小

                ES          要修改的块的段地址

    返回寄存器:进位标志清除表示成功

                进位标志置位表示出错

                AX          出错代码

                            07h,内存控制块被破坏

                            08h,内存不够

                            09h,无效的内存块地址

                BX          可用的最大块大小(如果AX=08h)

    注释:程序可使用这种功能调用来修改它们从调用功能48h中得到的内存块

    大小,或修改它们自己的内存分配。由于COM程序在运行时能获得全部的内

    存,因此,如果它们希望能够执行(EXEC)其它程序的话,就得调用这一功能。

    EXE程序也需要调用这种功能来释放内存,除非已修改了它们EXE标题中

    的MAXALLOC参数以使它们请求的内存少于全部内存。第10章“程序和内

    存管理”十分详细地介绍了程序执行方面的内存管理情况,这里就不再多谈。

      该功能还常常用作SETBLoCK功能。

系统

Int 21h           功能4Bh                                  版本2

                  执行程序(EXEC)

在其它程序的控制之下执行程序

 调用寄存器: AH              4Bh

              AL          00,装载并执行程序

                            01,装载但不执行程序

                            03,装载覆盖程序

                            05,进入Exec状态

              ES:BX      指向参数块的指针

              DS:DX      指向程序说明的指针

              DS:DX       指向ExecState结果的指针,定义如下(唯一的

                            子功能代码为05h):

                            00h(字),保留必须为0

                            02h(字),字节标志;位0=程序为一道EXE程

                            序,位1=程序是一道覆盖程序

                            04h双字),指向ASCIIZ程序名的指针(程序

557页

                          名中可以包括路径说明)

                          08h(字),用于新程序的PSP段

                          0Ah(双字),新程序的CS:IP

                          0Eh(双字),程序大小(包括PSP)

返回寄存器:进位标志清除表示成功。除CS和IP外的所有寄存器均被破

              坏,其中包括堆栈的指针。必须把SS和SP保存在本地的一个

              CS可定址的位置上,并且,只能在调用该功能之前以及在该功

              能返回之后进行保存。

              进位标志置位表示出错

              AX          出错代码

                          01h,无效功能

                          02h,文件未找到

                          05h,访问被禁止

                          08h,内存不够

                          0Ah,非法的环境

                         0Bh,无效的格式

注释:可在系统中使用这种EXEC功能来执行程序和管理覆盖。当系统完成

新的程序(子进程)时,原始程序改进程)就可重新获得控制权。如果子进程使

用的是传送返回代码的DOS终止功能,那么父进程就有可能从子进程那里接

收到退出代码。

    该功能还能装载覆盖程序。覆盖程序能组成程序段或数据。在程序执行

和覆盖操作之间的主要区别在于分配给程序的内存是系统中的自由内存,而

覆盖程序则被装入调用覆盖功能的程序业已拥有的内存中。而且,如果有必

要,则在执行其它程序之前,程序还应释放出内存(如满足COM程序的需

要)。

    对该操作进行控制的主要途径是通过ES:BX寄存器所指的参数块来进

行的。表16.15列出了参数块的格式。

                      表16.15参数块格式

偏移值字节      字段长度                内    容

    EXEC功能(AL=00h)

    00h               字                  指向环境块的段地址

    02h               字                  命令尾的偏移值

    04h               字                  命令尾的段

    06h               字                  第一个FCB(偏移值5Ch)的偏移值

    08h               字                  第一个FCB的段

    0Ah               字                  第二个FCB(偏移值6Ch)的偏移值

    0Ch               字                  第二个FCB的段

558页

偏移值字节      字段长度                  内      容

    Debug功能(AL=01h)

    00h               字                  指向环境块的段地址

    02h               字                  命令尾的偏移值

    04h               字                  命令尾的段

    06h               字                  第一个FCB(偏移值5Ch)的偏移值

    08h               字                  第一个FCB的段

    0Ah               字                  第二个FCB(偏移值6Ch)的偏移值

    0Ch               字                  第二个FCB的段

    0Eh               字                  已装载程序的SP

    10h               字                  已装载程序的SS

    12h               字                  已装载程序的IP

    14h               字                  已装载程序的CS

    覆盖功能(AL=03h)

    00h               字                  指向覆盖装点的指针

    02h               字                  适用于代码映象的重定位因子(仅适用于

                                          EXE文件)

      环境块是一系列的ASCIIZ字符串,其作用是可通过它们把环境信息传

送给系统正在执行的程序。对于这些字符串,既可通过SET功能将它们设置

在命令层,也可以在程序内部内在地创建出来。通常情况下,这些字符串除了

含有系统上特定的变量外,还包括COMSPEC变量(其中含有系统命令处理

程序COMMAND.COM)和PATH变量可执行的程序所存在的地方)。

      典型的环境块应是这个样子:

                              1               2             3               4

                1234567890123456789012345678901234567890

                COMPEC=c:\COMMAND.COM* PATH =c:\DOS*.*

其中星号代表NUL或零字节。如果环境块指针为零。那么子进程就会继承与

父进程相同的环境。在DOS版本3以及更高的版本中,环境块内的最末尾一

个零后面跟随着有一个双字节,该字节中含有一个字符计数和一个尾随其后

的ASCIIZ字符串,驱动器和正在执行的程序文件的路径名就是在这个字符

串中。

      命令尾就是一个字符串,它构成了要执行的命令之后的命令行。该命令行

的格式为开头是一个单字节的长度计数,中间是字符串,结尾是回车,总长度

不能超过128个字节。命令尾被保存在偏移量08h处的程序段前缀(PSP)中,

并且在进入程序之前,它所包含的只有128个字节。

      典型的命令尾是这样的:

559页

                            1               2             3             4

                1234567890123456789012345678901234567890

                #/C CHAPT1.DOC@

其中#是一个单数字字节,值为14,@则代表一个单字节的回车符。

      按照这个方式装入的子进程能继承父进程的I/O文件,除非在文件打开

调用(功能3Dh)中,父进程显式地规定了不继承。不过,标准文件仍然是打开

的。如果对用于父进程的标准文件进行了重定向,那么在用于子进程时,它们

能继续保存重定向。此外,父进程还能重定向文件(参见功能46h)。

      在调用该功能时,值得当心的是调用的顺序。在任何EXEC功能的执行

过程中,系统都必须假定所有寄存器都被修改过。因为该功能的目的是为了运

行另一道程序。当EXEC功能返回时,只能假设CS和IP是正确的。在调用

前,父进程至少必须把SS和SP(还可加上希望保存的其它寄存器)保存在可

通过CS段寄存器定址的位置中。在返回时,可以把SS和SP恢复到各自的初

始值,不过,必须在禁止中断的前提下进行恢复操作,这样便不致于让恢复操

作停止在半路上,从而也就避免了该系统出现不稳定的状态。

      只有在拥有足够的内存来装载目的程序时,EXEC功能才能获得成功,否

则它们就会失败。在调用EXEC之前,汇编语言程序必须使用功能4Ah释放

出所需要的内存。而对于C程序,当它启动时,它就会释放出多余的内存。关

于内存分配的详细情况,请参见第10章“程序和内存管理”。

      在DOS版本2中,该功能给人的印象就是毛病重重。这些问题的根源在

于程序员们想通过把寄存器压入堆栈来保存它们,由于有些版本不能保证正

确地设置CPU方向标志,其结果会导致系统立即挂起。要想避免这些问题,只

需在调用EXEC之前,作为设置操作的一部分,发出一道CLD指令。如果只在

DOS版本3以及更高的版本中使用程序,则这一切都是不必要的,因为检查

工作已交给DOS代码处理。

      有一则令人感兴趣的消息说:IBM的DOS 2.x版本中,该功能不是被物

理地定位在IBMDOS. COM文件中,而是构成了COMMAND.  COM。IBM的

一部分,这样做是为了节省空间;而其它的版本,如2.x系统则把该功能作为

MSDOS.SYS的一部分,这是IBM从3.0版本才开始采用的方法(这时已放

宽了把上述两种DOS文件连成整体的要求)。

      调试程序使用子功能01h来把程序装入内存,并让该程序作好执行准备。

Microsoft的DEBUG、SYMDEB和CODEVIEW调试程序以及Borland的

Turbo Debugger调试程序都使用这一功能。作为调试程序的一种特殊用法

是,在返回时,把装载程序的SS、SP、CS和IP寄存器值保存在ES:[BX+

0Eh]处。与未公开的子功能00h和03h一样,子功能01h在返回时会破坏所

有的寄存器内容;因此,在能够使用SS : SP和CS : IP值之前,程序员必须把

ES和BX寄存器值保存在能通过CS获取的地方。

(未完~~~待续。。。)

posted @ 2014-07-11 21:26  Chaobs  阅读(605)  评论(0编辑  收藏  举报