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

转载 2006年06月14日 23:44:00
一、 引言:
    如果大家用过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 100h
start: 
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
  lodsb
continue:
         push si
  cmp  al,'/'
  jz   parascanloop
         jmp  error      ;wrong parameter
judgespace:
         lodsb
;        call debug         ;set break point 
  cmp  al,0dh
  je   scanexit
  cmp  al,' '
  je   judgespace
  jne  continue
parascanloop:      ;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 char
scanexit:
         lea  dx,noparametermsg
  call disp
  call rettodos
choise:
         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 parameter
print:
         lea  dx,message
  call disp
  call rettodos
help:                       ;print the help message
         lea  dx,helpmsg
  call disp
  call rettodos
error:                      ;print the error parameter message
         lea  dx,wrongparamsg
  call disp
  mov  ax,0200h
         pop  si
  dec  si
prnwrongparameter:  
         lodsb
  cmp  al,0dh
  jz   retdos
  mov  dl,al
  int  21h
  loop prnwrongparameter
retdos:
         mov  dl,'"'
  int  21h
  mov  dl,'!'
  int  21h
  call rettodos
main endp

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

rettodos proc near
         mov  ah,4ch
  int  21h
rettodos 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  

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

一、 引言:    如果大家用过TurboC2.0/3.0 or BorlandC3.X等编译器编写DOS应用程序的话,编写一个命令行参数形式的应用程序对大家来说是一件非常容易的事情,只要在主函mai...
  • JessenChen
  • JessenChen
  • 2011年04月18日 14:11
  • 632

课程设计:汇编语言实现音乐播放器

原理如下:http://download.csdn.net/detail/zt1994223/8977995 1.发生原理 利用 8253/54 定时器驱动扬声器 计数器2用于发声时,一般采用模式3,...
  • zt1994223
  • zt1994223
  • 2015年08月08日 17:36
  • 2582

汇编语言子函数——64位减法运算

这个大数据的减法运算用到的指令是sbb指令,这个指令和大数据的加法指令adc有着相似的用法 sbb = sub - CF 大数据减法:mov ax, 0A8785428 mov bx, 0E58...
  • qq_23880193
  • qq_23880193
  • 2015年01月10日 14:01
  • 663

汇编语言简单小程序——运算类编程实验

运算类编程实验   欢迎大家阅读我的博客,如果有错误请指正,有问题请提问,我会尽我全力改正错误回答问题。在此谢谢大家。 实验目的 (1)掌握使用运算类指令及调试方法 (2)掌握运算类指令对各状态标...
  • qq923132714
  • qq923132714
  • 2017年11月28日 13:58
  • 271

小结:实验5 编写、调试具有多个段的程序

1.结论 (1)若未指定程序的入口,程序载入后cs指向第一个段,ip=0;  若指定了程序的入口,程序载入后cs指向指定入口的那个段的段地址,ip等于入口相对段地址的偏移 (2)一个段的大小至少...
  • BossLynn
  • BossLynn
  • 2015年01月23日 13:56
  • 662

汇编语言编程中应当注意的几大规范

1.压栈弹栈操作必须在同一个程序段中完成。同一个程序段的意思是:要么弹栈压栈都在主程序段,要么在某一个特定的子程序段。绝对不可以在主程序段压栈,在某个子程序段弹栈,看着好像这样可以在主程序与子程序段之...
  • zisishen4200
  • zisishen4200
  • 2016年11月27日 19:21
  • 365

汇编语言第一个程序

在win7里面编写汇编语言,下载DOSBox就能够在win7里运行编译汇编代码。 下载http://pan.baidu.com/s/1dEs92Rf安装DOSBox0.74-win32-install...
  • u010411264
  • u010411264
  • 2016年01月10日 19:48
  • 1838

使用汇编语言编写程序,设计一个用8051单片机控制的循环彩灯控制系统

使用汇编语言编写程序,设计一个用8051单片机控制的循环彩灯控制系统要求:1、能输出4种花型,并能由人工进行花型的切换。可以使用按键,也可以使用拨动开关来实现切换,方法不限。2、循环彩灯的循环速度可调...
  • baidu_33836580
  • baidu_33836580
  • 2016年01月25日 11:41
  • 1819

汇编语言实验:编写0号中断处理程序

汇编语言实验:编写0号中断处理程序任务:编写0号中断处理程序,使得在除法溢出发生时,在屏幕中间显示字符串“divide error!”,然后返回操作系统。下面写给出效果,再给出实现代码,最后给出设计思...
  • wyf12138
  • wyf12138
  • 2016年12月20日 23:41
  • 838

汇编语言调试DEBUG命令

汇编语言调试DEBUG命令   2007-06-04 21:07:16|  分类: 其他 |  标签:心情   |字号大中小 订阅   1、显示命令D...
  • dengziliang001
  • dengziliang001
  • 2013年01月06日 10:44
  • 1346
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:汇编语言命令参数程序的编写
举报原因:
原因补充:

(最多只允许输入30个字)