实验九 DOS 文件管理程序设计
一. 实验目的:
1. 掌握 DOS 系统的文件管理及调用方法
2. 了解使用程序段前缀
PSP 的方法
3. 了解程序加载过程及实现方法
二. 实验要求:
1. 掌握利用系统调用进行文件管理的方法
A 了解 FCB ( File Control Block ) 块进行文件操作的方法
B 掌握使用句柄进行文件操作的方法
C 掌握文件的建立、打开、读写及关闭方法
2. 程序段前缀
PSP 的使用
A PSP 各段含义及用途
B 掌握利用 PSP 各段进行编程的方法
3. 程序加载及实现
A DOS 下 EXEC 子功能的应用
B 加载程序的设计和实现
三. 实验仪器:
PC 机一台
四. 实验内容:
9.1 在当前目录建立一文件,文件内写入 "ABCDEFG...XYZ",然后在 DOS 下使用 TYPE 命令检查。
9.2 打开一内容为大写英文字母的文件,将其内容加一固定常数使其
变为小写,可用 TPYE 命令检察。
9.3 编一程序实现利用 PSP ,将参数表在屏幕上显示。
例如 程序名: ABC.EXE
则 >ABC WE ARE THE WORLD.
显示 WE ARE THE WORLD.
9.4 编一程序实现将文件根据参数表上的 +N ( 或 -N )命令,对其 内容进行加 N ( 或减 N ) 操作。可利用
ASCII 码表进行检查。
例如 程序名: PM_FILE.EXE
文件名: ASCII.DAT 内容: "ABC ... XYZ"
则 >PM_FILE ASCII.DAT +3
显示 DEF ... Z[/]
9.5 完成
DOS 下的 COPY 命令。
9.6 根据自定的规则,将文件进行加密。同时给出解密程序。
9.7 主程序实现功能选择,
根据输入分别执行加载不同的程序及退 出。
例如 主程序显示: " Please input choise
( 1,2,3 ) QUIT 4"
根据输入分别加载 PROG1.EXE PROG2.EXE PROG3.EXE
PROG1.EXE
功能: 显示 " NO ONE KNOWS "
PROG2.EXE
功能: 显示 " I PASS THE TEST "
PROG3.EXE
功能: 显示 " TO BE OR NOT TO BE "
9.8 自编题
五. 实验原理:
DOS 下的文件管理
DOS 支持两种文件服务功能,一种是早期的文件控制块
( FCB ),另一种是句柄方式 ( Handle )。采用 FCB 方式进行文件操作,由于 FCB 结构复杂,用户要在使用前自己开辟 FCB 区,给编程者增加了难度,目前已很少使用。
为了减轻编程者在面对文件管理编程时的负担,在
DOS V2.00 以上版本中采用了另外一种类似于 UNIX/XENIX 的文件服务方式,即句柄方式访问磁盘文件。用句柄方式访问文件比较简单,编程者只要按要求给出文件名的字符串,然后进行建立或打开操作后,
DOS 系统内部会自动建立文件控制块,并为该文件分配一通道号(称为该文件的句柄),利用该通道号,编程者就可根据需要对已给的文件名对应的文件进行操作。
句柄实际上就是 16 位的二进制数,与使用
FCB 方式相比,用户在进行文件操作时,只要在数据区内分配一个字单元保存句柄即可。
DOS 还将系统的标准设备用特定的字符定义,因此,使用这些设备时,也可象文件一样操作,例如,利用并行口打印文件,就可采用 PRN 的设备名 (与文件名使用方式相同) 打开设备,然后象写文件一样进行写操作即可,使用十分方便,(实际上, DOS 在建立时已将几个标准设备用句柄的方式打开,直接使用也可)。
使用句柄方式进行磁盘文件处理的过程:
1 程序应开辟以下存储区域
A. 文件名域 大小至少定义为所需文件名串长加 1 (若需要可包括驱动
器,路径,文件名和扩展名)
B. 句柄域 字定义
C. 缓冲区 进行文件处理的缓冲区,其大小无特殊要求,当然以大为佳, 大的缓冲区可减少读写盘次数.
2 获得需打开合法的文件名 ( 可程序中直接给出或利用 21H 功能
0AH,或利用 PSP).
3 在文件名后加一个 0 ,构成适合句柄处理的文件名串.
4 使用 INT 21H 功能 3CH 或 3DH 生成或打开文件,注意在打开文件时
CX一般应置 0 表示无特殊属性的文件, 调用后在 AX 中返回一个句柄,该句柄即可对应用户的文件.
利用 3CH 建立文件时, CX 的低字节表示文件的属性,要具有该属性可在该位置
1.
D0 : 只读文件
D1 : 隐含文件
D2 : 系统文件
D3 : 卷标
D4 : 子目录
D5 : 归档( Archive )
D6 : 未用
D7 : 未用
显然,利用对属性的不同设置,可以实现其它任务,如建立子目录等.
5 建立文件指针
6 读/写文件
7 关闭文件
与文件处理相关的系统调用
利用句柄进行文件操作的方法及实现
对文件的操作可分成以下几种方式,用户在使用时可参照给出的程序.
1 建立/删除文件
建立文件过程一般应首先判别该文件是否存在 (利用 4EH
功能),因为若文件已存在,重新建立会破坏已建立的文件内容 (将该文件长度置 0 )。
2 打开/关闭文件
建立文件过程包括打开操作,第一次应使用建立,以后的文件操作则由 "打开 " 文件开始。
关闭文件在程序中是必须的,因为没有按正常的关闭文件操作进行的话,有可能导致信息的丢失。
3 重新命名文件/移动文件目录
4 写顺序文件
5 读顺序文件
6 写随机文件
7 读随机文件
2 程序段前缀 PSP
PSP ( Program segment
prefix ) 称为程序段前缀,是 DOS 在加载外部命令或应用程序 ( .EXE 或 .COM 文件 ) 时,在加载的程序段前面设置的一个固定长度的信息区
( 共 100H 字节 ), PSP 包括以下四个组成部分:
供进程调用的 DOS 入口 PSP+0 , +2 , +5, +50H 和
+2CH 字段
供进程使用的传递参数 PSP+5CH, +6CH 和 +80H 字段
为 DOS 保存的中断向量 PSP+0AH, +0EH
, 和 +12H 字段
由 DOS 专用的保留区域 PSP+16H ~ 2BH 和
2EH ~ 37H 字段
PSP 的某些关键字段涉及到系统内部管理,所以使用者不得更改
PSP 的结构
段内偏移地址 分配情况
PSP+00H ~ 01H 程序终止中断 INT 20H
PSP+02H ~ 03H 可用内存空间高端段址
PSP+04H 备用
PSP+05H ~ 09H DOS 远调用入口
PSP+0AH ~ 0DH 程序结束处理中断向量保存处
PSP+0EH ~ 11H Ctrl-C 处理中断向量保存处
PSP+12H ~ 15H 严重错误处理中断向量保存处
PSP+16H ~ 17H 存放父进程
PSP 段址
PSP+18H ~ 2BH 系统打开文件表
PSP+2CH ~ 2DH 环境块段址
PSP+2EH ~ 31H 保存进入内核时用户栈双字指针
PSP+32H ~ 33H 指示系统打开文件表的大小
PSP+00H ~ 01H 指示系统打开文件表的地址
PSP+05H ~ 09H 备用
PSP+0AH ~ 0DH INT 21H 入口
PSP+0EH ~ 11H 备用
PSP+12H ~ 15H 用于特殊文件的扩展 FCB 的前缀
PSP+16H ~ 17H 存放格式化未打开的第一个 FCB
PSP+18H ~ 2BH 存放格式化未打开的第二个 FCB
PSP+2CH ~ 2DH 备用
PSP+2EH ~ 31H 未格式化参数长度
PSP+32H ~ 33H 未格式化参数内容
当可执行文件加载后,根据其不同的类型,系统会采用相应的方式进行处理。若用户程序是 .COM 文件,则加载后把程序装入程序段偏移量为 100H 处,并把所有的段寄存器指向 PSP,实际上,由于 .COM 文件是以长度小于
64K 为要求设计的,所有的程序,数据包括 PSP 都在同一段内。对于 .EXE 文件,加载后把程序的 DS 和 ES 指向 PSP 段,若要使用 PSP ,例如,要利用输入参数,可在程序的开始利用
DS或 ES 实现获取。当然,获取 PSP 的段址也可以利用以下介绍的系统调用实现。
对编程者而言,在 PSP 中较为有用的是参数区,参数是通过在程序执行开始时,利用空格与之分隔的字符串,用回车表示结束,具体的说,就是程序和参数在同一行输入。当程序加载时,系统将参数及参数长度填入
PSP+80H 开始的参数区,其中 80H 处是参数长度,参数由 81H 开始存放。
PSP 在 DOS 中十分重要,以至于 DOS 专门为其设置了系统服务功能,以下给出了与
PSP 有关的系统调用:
与 PSP 有关的 5 个系统服务功能
名 称 功能号 入口值 出口值 版本
建立新 PSP 26H DX=新 PSP 段址 DS 指向新建的 PSP DOS 1.X
置当前PSP段址 50H BX=当前 PSP 段址
/ DOS 2.X
取当前PSP段址 51H / BX=当前 PSP 段址
DOS 2.X
建立新PSP 55H DX=新PSP段址 DS 指向新建 PSP DOS 2.X
取当前PSP段址 62H / BX=当前 PSP 段址
DOS 3.X
DOS 技术资料只公开了 2 个功能: 26H 和 62H。没有公开的功能建议避免使用。此外, 26H 功能也建议避免使用,在 DOS 的 4BH 功能
( EXEC )中,不仅包括建立 PSP,还增加了进程的加载和执行的新操作,对一般使用来说,单独申请 PSP是比较少的。
3. 程序加载及实现
所谓 "加载" 就是在
DOS 环境下,PC 机从磁盘上将可执行文件(即 DOS 下的 .EXE 文件和 .COM 文件)装入到内存的过程。加载的过程包括程序装入内存的分配方案,加载是否成功,装入后
CPU 各寄存器内容及包括的信息等,对编程者而言,掌握一般的加载后信息分配,在某些应用场合中,了解和掌握如何在自己的程序中加载新的程序并使之运行的方法是非常有用的。
我们知道, DOS 下允许用户键入的命令有
DOS 内部命令,DOS 外部命令,可执行的应用程序及批处理文件,对同名的可执行文件按 .COM 到 .EXE 的优先顺序处理,具体的说,DOS 加载可执行文件是通过
EXEC 子功能实现的 ( 即 INT 21H 的 AH=4BH )。由于 .COM 和 .EXE 文件的结构不同,它们在加载的实际过程及装入内存方式是不同的,所以,对待不同的文件应有不同的处理方式。
加载 .EXE 文件后,各寄存器的初值设置
1) DS 和 ES 指向 PSP 的段地址
2) CS 指向代码段的绝对段址
3) SS 指向堆栈段的绝对段址
4) IP 指向代码段入口时第一条指令的偏移地址
5) SP 指向堆栈段如口时深度,此值由文件头位移
10H 的字域决定
6) BX, CX 是加载程序的字节长度
加载 .COM 文件后,各寄存器的初值设置
1) CS,DS,ES 和 SS 指向 PSP 的段地址
2) IP 固定为 100H
3) SP 位 FFFEH ,并在栈顶出压入一全 0 字
4) BX, CX 是 COM 文件的字节长度
A DOS 下 EXEC 子功能的应用
B 加载程序的设计和实现
_