一、 引言:
如果大家用过TurboC2.0/3.0 or BorlandC3.X等编译器编写DOS应用程序的话,编写一个命令行参数形式的应用程序对大家来说是一件非常容易的事情,只要在主函main()中加几个参数就OK(int main(int argc,char *argv,char *env){})。相对汇编语言来说编写一个命令行参数的程序就比较艰难,它要用到DOS的
程序段前缀PSP(Program Segment Prefix)知识以及其他相关DOS知识。(本文只对参数介绍,环境块不作讨论)
二、相关知识:
在DOS的提示符下键入一个命令(内/外部命令)或程序的名字,DOS SHELL(COMMAND.COM)首先根据名字判别其是内部命令还是外部命令或用户程序,若是内部命令则调用COMMAND.COM暂驻在内存中的部分的DOS内部命令代码,若是外部命令或用户程序,DOS SHELL则在当前目录和搜索路径中
搜索匹配的文件名,找到了就加载
程序,加载出错显示错误信息,找不到则显示Bad command or file name。
用户载DOS提示符下输入一串字符串,DOS SHELL把以回车(0Dh)为结束的这以字符串作为一个命令和参数进行解释,第一个空格以前的字符串为命令名(必须符合DOS命名规则),第一个空格(包括空格)到回车之间的字符作为命令或
程序的参数。
程序段前缀--PSP是DOS加载一个外部命令或用户程序(扩展名为COM or EXE)时,在程序段前设置一个以节为边界,固定长度为10H(即256字节,一节为16字节)的存储块,PSP和程序段共有一个内存控制块(MCB),PSP位于每个程序的开始部分,无论是COM还是EXE,PSP的数据结构是相同的。PSP是程序与DOS的接口,DOS利用PSP管理进程,DOS用户进程指的是一个已被装入内存的可执行程序或已被调入内存但未执行的程序,COMMAND.COM是一个最早被装入内存的程序,因而可被看作祖先进程,外部命令或用户程序作为子进程,被DOS通过INT 21H的4BH号子功能来加载。用户
程序也可以通过INT 21H的4BH号子功能调用来加载自己的子进程,控制子进程的执行,并通过4DH号子功能调用获取子进程的运行状况。
PSP中存有许多关于程序启动、执行、结束以及进程调度、进程环境地址和进程标志等重要信息。
程序利用PSP还可以控制父子进程间的通信。至于PSP的数据结构的详细内容请参考有关书籍,本文不详细给出。
DOS加载一个COM或EXE程序时,段寄存器DS,ES都指向PSP段址(PSP段址是进程的唯一标志符),而不是指向
程序的数据段和附加段。COM文件的CS,SS也指向PSP的段址。EXE文件的CS,SS,IP和SP需要进行重定位。
DOS加载一个外部命令或用户程序时,把文件名之后到回车符之间的字符串,最多可达127个字符作为参数,并把这些字符串送到PSP位移81H开始的区域,位移80H的一个字节存放参数字符串长度(回车符不算在内)。大家可用DEBUG.EXE加载一个带参数的程序,然后用D DS:80子命令查看加载
程序的参数。命令行参数一般以空格(20H)为开始,回车符(0DH)为结束,但命令行中的重定向,管道符以及有关信息不作为参数传递给PSP。
三、示例
程序:
本例程序PARATEST.ASM在没有参数(参数为一连串空格也视为无参数)的情况下显示提示信息,程序以字符''/''作为参数的标志,''/''后的字符是参数,根据不同的参数显示不同的字符串,并忽略''/''前的空格。程序还把非法参数显示出来,由于程序中保存参数的单元只设了两BYTES,如果字符''/''后的第一格字符是合法参数,
程序不管字符''/''后有多少个字符都认为是合法的。
顺便介绍一个汇编编程的技巧,文后附带的示例源程序(PAR