home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / advos2 / ch19 / asmhelp.asm next >
Encoding:
Assembly Source File  |  1988-12-12  |  8.6 KB  |  277 lines

  1.     title    ASMHELP -- Sample MASM DLL
  2.         page    55,132
  3.     .286
  4.  
  5. ; ASMHELP.ASM
  6. ;
  7. ; Source code for the MASM dynlink library ASMHELP.DLL.
  8. ;
  9. ; Assemble with:  C> masm asmhelp.asm;
  10. ; Link with:  C> link asmhelp,asmhelp.dll,,os2,asmhelp
  11. ;
  12. ; Exports two routines for use by MASM programs:
  13. ;
  14. ; ARGC  Returns count of command line arguments.
  15. ;       Treats blanks and tabs as whitespace.
  16. ;
  17. ;       Calling sequence:
  18. ;
  19. ;       push    seg argcnt      ; receives argument count
  20. ;       push    offset argcnt
  21. ;       call    ARGC
  22. ;
  23. ; ARGV  Returns address and length of specified
  24. ;       command line argument.  If called for 
  25. ;       argument 0, returns address and length
  26. ;    of fully qualified pathname of program.
  27. ;
  28. ;       Calling sequence:
  29. ;
  30. ;       push    argno           ; argument number
  31. ;       push    seg argptr      ; receives argument address
  32. ;       push    offset argptr
  33. ;       push    seg arglen      ; receives argument length
  34. ;       push    offset arglen
  35. ;       call    ARGV
  36. ;
  37. ; Copyright (C) 1988 Ray Duncan
  38. ;
  39.  
  40. tab     equ     09h             ; ASCII tab
  41. blank   equ     20h             ; ASCII space character
  42.  
  43.         extrn   DosGetEnv:far
  44.  
  45. DGROUP  group   _DATA
  46.  
  47.  
  48. _DATA   segment word public 'DATA'
  49.  
  50. envseg  dw      ?               ; environment selector
  51. cmdoffs dw      ?               ; command tail offset
  52.  
  53. _DATA   ends
  54.  
  55.  
  56. _TEXT   segment word public 'CODE'
  57.  
  58.         assume  cs:_TEXT,ds:DGROUP
  59.  
  60.                                 ; parameter for argc
  61. argcnt  equ     [bp+6]          ; receives argument count
  62.  
  63.         public  argc
  64. argc    proc    far             ; count command line arguments
  65.  
  66.         push    bp              ; make arguments addressable
  67.         mov     bp,sp
  68.  
  69.         push    ds              ; save registers
  70.         push    es
  71.         push    bx
  72.         push    cx
  73.  
  74.         mov     ax,seg DGROUP   ; point to instance data
  75.         mov     ds,ax
  76.  
  77.         mov     es,envseg       ; set ES:BX = command line
  78.         mov     bx,cmdoffs
  79.  
  80.         mov     ax,1            ; initialize argument count
  81.  
  82. argc0:  inc     bx              ; ignore useless first field
  83.         cmp     byte ptr es:[bx],0      
  84.         jne     argc0
  85.  
  86. argc1:  mov     cx,-1           ; set flag = outside argument
  87.  
  88. argc2:  inc     bx              ; point to next character 
  89.  
  90.         cmp     byte ptr es:[bx],0
  91.         je      argc3           ; exit if null byte
  92.  
  93.         cmp     byte ptr es:[bx],blank
  94.         je      argc1           ; outside argument if ASCII blank
  95.  
  96.         cmp     byte ptr es:[bx],tab    
  97.         je      argc1           ; outside argument if ASCII tab
  98.  
  99.                                 ; otherwise not blank or tab,
  100.         jcxz    argc2           ; jump if already inside argument
  101.  
  102.         inc     ax              ; else found argument, count it
  103.         not     cx              ; set flag = inside argument
  104.         jmp     argc2           ; and look at next character
  105.  
  106. argc3:                          ; store result into
  107.                                 ; caller's variable...
  108.  
  109.         les     bx,argcnt       ; get address of variable
  110.         mov     es:[bx],ax      ; store argument count
  111.  
  112.         pop     cx              ; restore registers
  113.         pop     bx
  114.         pop     es
  115.         pop     ds
  116.         pop     bp
  117.  
  118.         xor     ax,ax           ; signal success
  119.  
  120.         ret     4               ; return to caller      
  121.                                 ; and discard parameters
  122. argc    endp
  123.  
  124.  
  125.  
  126.                 ; parameters for argv...
  127. argno   equ     [bp+14]         ; argument number
  128. argptr  equ     [bp+10]         ; receives argument pointer
  129. arglen  equ     [bp+6]          ; receives argument length
  130.  
  131.         public  argv
  132. argv    proc    far        ; get address and length of
  133.                                 ; command tail argument
  134.  
  135.         push    bp              ; make arguments addressable
  136.         mov     bp,sp
  137.  
  138.         push    ds              ; save registers
  139.         push    es
  140.         push    bx
  141.         push    cx
  142.         push    di      
  143.  
  144.         mov     ax,seg DGROUP   ; point to instance data
  145.         mov     ds,ax
  146.  
  147.         mov     es,envseg       ; set ES:BX = command line
  148.         mov     bx,cmdoffs
  149.  
  150.         mov     ax,argno        ; get argument number
  151.         or      ax,ax           ; requesting argument 0?
  152.         jz      argv8           ; yes, get program name
  153.  
  154. argv1:  inc     bx              ; scan off first field
  155.         cmp     byte ptr es:[bx],0      
  156.         jne     argv1
  157.  
  158.         xor     ah,ah           ; initialize argument counter
  159.  
  160. argv2:  mov     cx,-1           ; set flag = outside argument
  161.  
  162. argv3:  inc     bx              ; point to next character 
  163.  
  164.         cmp     byte ptr es:[bx],0
  165.         je      argv7           ; exit if null byte
  166.  
  167.         cmp     byte ptr es:[bx],blank
  168.         je      argv2           ; outside argument if ASCII blank
  169.  
  170.         cmp     byte ptr es:[bx],tab    
  171.         je      argv2           ; outside argument if ASCII tab
  172.  
  173.                                 ; if not blank or tab...
  174.         jcxz    argv3           ; jump if inside argument
  175.  
  176.         inc     ah              ; else count arguments found
  177.         cmp     ah,al           ; is this the one?
  178.         je      argv4           ; yes, go find its length
  179.  
  180.         not     cx              ; no, set flag = inside argument
  181.         jmp     argv3           ; and look at next character
  182.  
  183. argv4:                          ; found desired argument, now
  184.                                 ; determine its length...
  185.         mov     ax,bx           ; save param. starting address 
  186.  
  187. argv5:  inc     bx              ; point to next character
  188.  
  189.         cmp     byte ptr es:[bx],0
  190.         je      argv6           ; found end if null byte
  191.  
  192.         cmp     byte ptr es:[bx],blank
  193.         je      argv6           ; found end if ASCII blank
  194.  
  195.         cmp     byte ptr es:[bx],tab    
  196.         jne     argv5           ; found end if ASCII tab
  197.  
  198. argv6:  xchg    bx,ax           ; set ES:BX = argument address
  199.         sub     ax,bx           ; and AX = argument length
  200.         jmp     argv10          ; return to caller
  201.  
  202. argv7:  mov     ax,1            ; set AX != 0 indicating  
  203.                                 ; error, argument not found
  204.         jmp     argv11          ; return to caller
  205.  
  206. argv8:                ; special handling for argv = 0
  207.         xor     di,di           ; find the program name by
  208.         xor     al,al           ; first skipping over all the
  209.         mov     cx,-1           ; environment variables...
  210.         cld
  211.  
  212. argv9:    repne scasb        ; scan for double null (can't use SCASW
  213.     scasb            ; because it might be odd address)
  214.         jne     argv9           ; loop if it was a single null
  215.  
  216.         mov     bx,di           ; save program name address
  217.         mov     cx,-1           ; now find its length... 
  218.         repne scasb             ; scan for another null byte
  219.  
  220.         not     cx              ; convert CX to length 
  221.         dec     cx
  222.         mov     ax,cx           ; return length in AX
  223.  
  224. argv10:                         ; at this point AX = length,
  225.                                 ; ES:BX points to argument
  226.  
  227.         lds     di,argptr       ; address of 1st variable
  228.         mov     ds:[di],bx      ; store argument pointer
  229.         mov     ds:[di+2],es
  230.  
  231.     lds    di,arglen    ; address of second variable
  232.         mov     ds:[di],ax      ; store argument length
  233.  
  234.     xor    ax,ax        ; AX = 0 to signal success
  235.  
  236. argv11:                         ; common exit point
  237.  
  238.         pop     di              ; restore registers
  239.         pop     cx
  240.         pop     bx
  241.         pop     es
  242.         pop     ds
  243.         pop     bp
  244.  
  245.         ret     10              ; return to caller      
  246.                                 ; and discard parameters
  247. argv    endp
  248.  
  249.  
  250. init    proc    far             ; DLL instance initialization
  251.  
  252.                                 ; get environment selector 
  253.                                 ; and offset of command tail
  254.                                 ; for this process...
  255.  
  256.         push    seg DGROUP      ; receives environment selector
  257.         push    offset DGROUP:envseg
  258.         push    seg DGROUP      ; receives command tail offset
  259.         push    offset DGROUP:cmdoffs
  260.         call    DosGetEnv       ; transfer to OS/2      
  261.         or      ax,ax           ; call successful?
  262.         jnz     init1           ; no, initialization error
  263.  
  264.         mov     ax,1            ; initialization OK,
  265.         ret                     ; return AX = 1 for success
  266.  
  267. init1:  xor     ax,ax           ; initialization failed,
  268.         ret                     ; return AX = 0 for error
  269.  
  270. init    endp
  271.  
  272.  
  273. _TEXT   ends
  274.  
  275.         end     init            ; initialization entry point
  276.