ITEEDU

7.4 FCB完结篇

7.4导航:第一页 第二页

这一节我们要讨论有关FCB的一些较为特殊的应用,主要是三个方面的内容:一是应用FCB删除文件和给文件改名;其二是利用扩展FCB访问具有特殊属性的文件。第三是有关"命令行参数"的问题。我们先来讨论第一个问题--删除与改名。

功能号: 13H
用 途: 删除文件
参 数: DS:DX--指向未打开的FCB
调 用: INT 21H
返 回: AL = 0--文件正确删除
AL = 0FFH--文件未能删除

功能号: 17H
用 途: 文件改名
参 数: DS:DX--指向特殊的FCB
调 用: INT 21H
返 回: AL = 0--文件正确改名
AL = 0FFH--文件未能改名

这两个功能在应用时应注意这样几点:首先要注意它们所使用的FCB的性质,13H功能要求使用一个未打开的FCB,17H功能使用一个特殊的FCB。下面我们就来看看特殊的FCB是一种什么结构,请看图7-4:

图7-4 特殊的FCB结构

可以看到和标准的FCB相比这个新的FCB主要是对偏移11H后作了改进,很显然,既然要改名,总要给出一个新的文件名才行,这个新文件名就填在FCB偏移11H处。第二我们要讨论一下究竟什么文件可以删除。我们平常使用DOS时都知道只读文件或隐含文件是不能删除的,那么使用13H功能删除文件时也要遵守这个规矩。同样,若不使用扩展FCB,那么卷标、子目录也不能用此功能删除,这个功能唯一能删除的就是那些普通的文件。第三,我们平常使用DOS时都知道DEL命令可以一次删除一批文件,也就是使用"*"或"?",我们习惯上称这两个符号为通配符。13H功能同样支持通配符,也就是说你在FCB中填入的文件名可以是"*.*"或"FILE.???"这样的字符串。当然,使用通配符是有条件的,并非所有的DOS版本都支持通配符,2.1版仅支持".",3.0以上版才支持"*"。考虑到现在所使用的DOS版本都在3.3以上,所以大家可以不必判断DOS版本而放心使用通配符。

下面这两个程序演示了这两个功能的使用方法,对于我们平时编制程序来讲,这两个功能其实并不常用,所以大家对它们的用法有些印象也就可以了,不必深究。

CHANAME.ASM
        DATA  SEGMENT
              ASSUME    DS:DATA
        FCB1  LABEL     BYTE
      DRIVE1  DB        0	;驱动器号,0:当前 1:A 2:B ...
    OLD_NAME  DB        'CONFIG '	;文件原名
     OLD_EXT  DB        'SYS'	;原扩展名
              DB        5 DUP(0)
    NEW_NAME  DB        'ABCDEFGH'	;新文件名
     NEW_EXT  DB        'LCS'	;新扩展名
         MSG  DB        'OK!!!',0DH,0AH,24H
        DATA  ENDS
			
        CODE  SEGMENT
              ASSUME    CS:CODE
        MAIN  PROC      FAR
              MOV       AX,DATA
              MOV       DS,AX
			
              MOV       AH,17H	;选择DOS的17H功能
              MOV       DX,OFFSET FCB1	;DX指向特殊的FCB
              INT       21H	;将文件改名
              OR        AL,AL	;文件已经改变名字了吗?
              JNZ       ERR_EXIT	;未能找到指定的文件,转ERR_EXIT
			
              MOV       AH,9	;显示"OK!!!"
              MOV       DX,OFFSET MSG
              INT       21H
   ERR_EXIT:
              MOV       AH,4CH	;结束进程
              INT       21H
        MAIN  ENDP
        CODE  ENDS
              END       MAIN
			
DELFILE.ASM			
        DATA  SEGMENT
              ASSUME    DS:DATA
        FCB2  LABEL     BYTE
      DRIVE2  DB        0	;驱动器号,0:当前 1:A 2:B ...
   FILE_NAME  DB        '* '	;文件名
    EXT_NAME  DB        'BAK'	;扩展名
  CUR_BLOCK2  DW        ?	;当前记录块号
   REC_SIZE2  DW        ?	;记录长度
  FILE_SIZE2  DW        2 DUP(?)	;文件长度,由系统填入
  CREA_DATE2  DW        ?	;建立或最后修改的日期,由系统填入
   POSITION2  DB        10 DUP(?)	;保留空间,由系统填入
    CUR_REC2  DB        ?	;当前记录号
    REL_REC2  DW        2 DUP(?)	;相对记录号
         MSG  DB        'OK!!!',0DH,0AH,24H
        DATA  ENDS
			
        CODE  SEGMENT
              ASSUME    CS:CODE
        MAIN  PROC      FAR
              MOV       AX,DATA	;初始化DS寄存器
              MOV       DS,AX
			
              MOV       AH,13H	;选择DOS的13H功能
              MOV       DX,OFFSET FCB2	;DX指向未打开的FCB
              INT       21H	;删除指定的文件
              OR        AL,AL	;文件删除了吗?
              JNZ       ERR_EXIT	;未能找到指定的文件,转ERR_EXIT
			
              MOV       AH,9	;显示"OK!!!"
              MOV       DX,OFFSET MSG
              INT       21H
   ERR_EXIT:
              MOV       AH,4CH	;结束进程
              INT       21H
        MAIN  ENDP
        CODE  ENDS
              END       MAIN

我们要讨论的第二个问题是个比较重要的内容,尽管这部分内容也不常用,但它是FCB文件功能与文件句柄功能的一个最显著的区别。我们知道存在于磁盘上的内容不仅是文件,还有子目录和卷标。即使是文件也有只读、隐含等很多种不同的属性。如何处理这些具有属性的文件,这就要用到扩展的FCB。我们前面讨论过有关文件属性的问题,DOS实际上是用一个字节表示文件属性,这个字节存放在扩展FCB的最后,也就是紧挨着驱动器号前面的那个字节。有关这方面的知识请大家复习一下本章的第二节。我准备通过一个实际程序来说明这个问题,请看例程LABEL.ASM

LABEL.ASM
        DATA  SEGMENT
              ASSUME    DS:DATA
     EXT_FCB  LABEL     BYTE
              DB        0FFH	;扩展FCB标志
              DB        5 DUP(0)
              DB        00001000B	;属性字节(磁盘卷标)
      DRIVE2  DB        0	;驱动器号,0:当前 1:A 2:B ...
   FILE_NAME  DB        '* '	;文件名
    EXT_NAME  DB        '* '	;扩展名
              DB        5 DUP(0)
    NEW_NAME  DB        'ABCDEFGHIJK'
			
         MSG  DB        'OK!!!',0DH,0AH,24H
        DATA  ENDS
			
        CODE  SEGMENT
              ASSUME    CS:CODE
        MAIN  PROC      FAR
              MOV       AX,DATA	;初始化DS寄存器
              MOV       DS,AX
              MOV       AH,17H	;选择文件改名功能
              MOV       DX,OFFSET EXT_FCB	;DX指向特殊的FCB
              INT       21H	;修改磁盘卷标
              OR        AL,AL	;改名功能执行正确吗?
              JNZ       ERR_EXIT	;若不正确,转ERR_EXIT
			
              MOV       AH,9	;显示"OK!!!"
              MOV       DX,OFFSET MSG
              INT       21H
   ERR_EXIT:
              MOV       AH,4CH	;结束进程
              INT       21H
        MAIN  ENDP
        CODE  ENDS
              END       MAIN

这个小程序可以将当前盘上的卷标改成"ABCDEFGHIJK",请注意我们在扩展FCB中定义的属性字节,其Bit3位为1,这说明我们要改名的是磁盘卷标而非其它的文件。如果将属性字节改成10H,则这个程序可以改子目录名。当然,改子目录名时就不能使用"*.*"了。后面我们还要讲文件句柄功能,那些功能也能处理有属性的文件,但它们都不能完成对卷标和子目录名的操作。