汇编语言命令参数程序的编写

    技术2022-05-11  149

                            汇编语言命令参数程序的编写一、 引言:    如果大家用过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,如果字符'/'后的第一格字符是合法参数,程序不管字符'/'后有多少个字符都认为是合法的。    顺便介绍一个汇编编程的技巧,文后附带的示例源程序(PARATEST.ASM)中的DEBUG子程序是利用了INT 21H的07H号子功能等待用户的键盘输入,相当于TURBOC中的getch()函数,作为程序的断点。我们还可以利用其显示断点的调试信息(包括各寄存器的值)。但注意保存现场,并进行现场恢复。

    四、结束语:    一个月以前我还只是会看别人的汇编程序,自从自己动手写程序后,自己的汇编编程水平有了很大的进步。写程序的过程中遇到问题,然后自己看书自己解决问题,这样学习汇编编程比光看书更有效。我的汇编编程的水平还很菜鸟,我会不断提高自己的水平,同时也希望与广大编程爱好者交流。

    附:源程序(PARATEST.ASM); ************************************************; * Program:Use asm language to creat a command  *; *         line and parameter program.          *; *==============================================*; * Designer:Howard   Original Place:Wuhan       *; * Creat Date:09/30/1999                        *; * Modification Date:10/05/1999                 *; * Now Version:1.0                              *; * Pass:Tasm 5.0,Tlink 3.1                      *; *==============================================*; *       Modification History                   *; *----------------------------------------------*; * Version 1.0 1.Command line and parameter     *; * 09/30/1999    test program.                  *; *----------------------------------------------*; * Version 1.1 2.Add the spaces parameters jud- *; * 10/05/19999   gement.                        * ; ************************************************;

    .model small.386.code  org 100hstart:  main proc far         push cs  pop  ds  ;ds=psp seg address  cld             ;cf=0  mov  si,81h  ;psp+81h is the first parameter char           lea  bx,parameter  ;parameter address(offset) saved to bx       ;unit parameter is used to save the parameter         lodsb      ;load a byte from [si] to al,and si=si+1  cmp  al,0dh     ; Enter?  jz   scanexit     ;if yes then scan parameter end  cmp  al,' '  jz   judgespace  lodsbcontinue:         push si  cmp  al,'/'  jz   parascanloop         jmp  error      ;wrong parameterjudgespace:         lodsb;        call debug         ;set break point    cmp  al,0dh  je   scanexit  cmp  al,' '  je   judgespace  jne  continueparascanloop:      ;saved the parameter to unit parameter         mov  [bx],al     ;save al to [bx],just save the parameters  lodsb  cmp  al,0dh     ;Enter?  jz   choise     ;if yes then jump choise  inc  bx  jnb  parascanloop  ;the next charscanexit:         lea  dx,noparametermsg  call disp  call rettodoschoise:         lea  si,parameter  mov  al,[si+1]     ;load the parameter to al  cmp  al,'?'     ;judge the parameter and choose                                              ;the different process   jz   help  cmp  al,'p'  jz   print  cmp  al,'P'  jz   print  jmp  error     ;wrong parameterprint:         lea  dx,message  call disp  call rettodoshelp:                       ;print the help message         lea  dx,helpmsg   call disp  call rettodoserror:                      ;print the error parameter message         lea  dx,wrongparamsg  call disp  mov  ax,0200h         pop  si  dec  siprnwrongparameter:            lodsb  cmp  al,0dh  jz   retdos  mov  dl,al  int  21h  loop prnwrongparameterretdos:         mov  dl,'"'  int  21h  mov  dl,'!'  int  21h  call rettodosmain endp

    disp proc near         mov  ah,09h  int  21h  retdisp endp

    rettodos proc near         mov  ah,4ch  int  21hrettodos endp ;;set a break point;debug proc near;        push ax dx;  mov  ax,0900h;  mov  dx,offset debugmsg;  int  21h;  mov  ax,0700h;  int  21h;  pop  dx;  pop  ax;debug endp  ;debugmsg db 0dh,0ah,'Program stop here,press any key to continue...','$' 

    noparametermsg db 0ah,0dh,'There is no parameter,enter paratest /? for help.','$'message   db 0dh,0ah,'This is a parameter test program.','$'wrongparamsg db 0dh,0ah,'The wrong parameter:"','$'helpmsg   db 0dh,0ah,'1.Paratest /?'          db 0dh,0ah,'  Print the help message.'   db 0dh,0ah,'2.Paratest /p'   db 0dh,0ah,'  Print the test message.','$'parameter db 2 dup(?)  end start  

     


    最新回复(0)