home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / advos2 / ch08 / argv.asm < prev    next >
Encoding:
Assembly Source File  |  1988-12-12  |  4.8 KB  |  138 lines

  1.     title    ARGV -- Return Argument Pointer
  2.         page    55,132
  3.         .286
  4.  
  5. ;
  6. ; ARGV.ASM
  7. ;
  8. ; Return address and length of specified command line argument
  9. ; or fully qualified program name.  Treats blanks and tabs as
  10. ; whitespace.
  11. ;
  12. ; Assemble with:  C> masm argv.asm;
  13. ;
  14. ; Call with:    AX    = argument number (0 based)
  15. ;
  16. ; Returns:      ES:BX = argument address
  17. ;        AX    = argument length (0 = no argument)
  18. ;
  19. ; Uses:         nothing (other registers preserved)
  20. ;
  21. ; Note:  If called with AX=0 (argv[0]), returns ES:BX
  22. ; pointing to fully qualified program name in environment 
  23. ; block and AX=length.
  24. ;
  25. ; Copyright (C) 1987 Ray Duncan
  26. ;
  27.  
  28. tab     equ     09h             ; ASCII tab
  29. blank   equ     20h             ; ASCII space character
  30.  
  31.         extrn   DosGetEnv:far
  32.  
  33. _TEXT   segment word public 'CODE'
  34.  
  35.         assume  cs:_TEXT
  36.  
  37.         public  argv            ; make ARGV available to Linker
  38.  
  39.                                 ; local variables...
  40. envseg  equ     [bp-2]          ; environment segment
  41. cmdoffs equ     [bp-4]          ; command line offset   
  42.  
  43. argv    proc    near
  44.  
  45.         enter   4,0             ; make room for local variables
  46.         push    cx              ; save original CX and DI 
  47.         push    di
  48.  
  49.         push    ax              ; save argument number
  50.  
  51.         push    ss              ; get selector for environment 
  52.         lea     ax,envseg       ; and offset of command line 
  53.         push    ax
  54.         push    ss
  55.         lea     ax,cmdoffs
  56.         push    ax
  57.         call    DosGetEnv       ; transfer to OS/2      
  58.         or      ax,ax           ; test operation status
  59.         pop     ax              ; restore argument number
  60.         jnz     argv7           ; jump if DosGetEnv failed
  61.  
  62.         mov     es,envseg       ; set ES:BX = command line
  63.         mov     bx,cmdoffs
  64.  
  65.     or    ax,ax        ; is requested argument = 0?
  66.         jz      argv8           ; yes, jump to get program name
  67.  
  68. argv0:  inc     bx              ; scan off first field
  69.         cmp     byte ptr es:[bx],0      
  70.         jne     argv0
  71.  
  72.         xor     ah,ah           ; initialize argument counter
  73.  
  74. argv1:  mov     cx,-1           ; set flag = outside argument
  75.  
  76. argv2:  inc     bx              ; point to next character 
  77.         cmp     byte ptr es:[bx],0
  78.         je      argv7           ; exit if null byte
  79.         cmp     byte ptr es:[bx],blank
  80.         je      argv1           ; outside argument if ASCII blank
  81.         cmp     byte ptr es:[bx],tab    
  82.         je      argv1           ; outside argument if ASCII tab
  83.  
  84.                                 ; if not blank or tab...
  85.         jcxz    argv2           ; jump if already inside argument
  86.  
  87.         inc     ah              ; else count arguments found
  88.         cmp     ah,al           ; is this the one we're looking for?
  89.         je      argv4           ; yes, go find its length
  90.         not     cx              ; no, set flag = inside argument
  91.         jmp     argv2           ; and look at next character
  92.  
  93. argv4:                          ; found desired argument, now
  94.                                 ; determine its length...
  95.     mov    ax,bx        ; save parameterr starting address
  96.  
  97. argv5:  inc     bx              ; point to next character
  98.         cmp     byte ptr es:[bx],0
  99.         je      argv6           ; found end if null byte
  100.         cmp     byte ptr es:[bx],blank
  101.         je      argv6           ; found end if ASCII blank
  102.         cmp     byte ptr es:[bx],tab    
  103.         jne     argv5           ; found end if ASCII tab
  104.  
  105. argv6:  xchg    bx,ax           ; set ES:BX = argument address
  106.         sub     ax,bx           ; and AX = argument length
  107.         jmp     argvx           ; return to caller
  108.  
  109. argv7:  xor     ax,ax           ; set AX = 0, argument not found
  110.         jmp     argvx           ; return to caller
  111.  
  112. argv8:                          ; special handling for argv=0
  113.         xor     di,di           ; find the program name by
  114.         xor     al,al           ; first skipping over all the
  115.         mov     cx,-1           ; environment variables...
  116.         cld
  117. argv9:  repne scasb             ; scan for double null (can't use
  118.     scasb            ; SCASW since might be odd address)
  119.         jne     argv9           ; loop if it was a single null
  120.         mov     bx,di           ; save program name address
  121.         mov     cx,-1           ; now find its length... 
  122.         repne scasb             ; scan for another null byte
  123.         not     cx              ; convert CX to length 
  124.         dec     cx
  125.         mov     ax,cx           ; return length in AX
  126.  
  127. argvx:                          ; common exit point
  128.         pop     di              ; restore original CX and DI
  129.         pop     cx
  130.         leave                   ; discard stack frame
  131.         ret                     ; return to caller
  132.  
  133. argv    endp
  134.  
  135. _TEXT   ends
  136.  
  137.         end     
  138.