程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 匯編語言 >> 匯編語言命令參數程序的編寫

匯編語言命令參數程序的編寫

編輯:匯編語言

一、 引言:

如果大家用過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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved