home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / SKEL32.ZIP / SKELOS32.ASM < prev    next >
Assembly Source File  |  1992-09-20  |  10KB  |  297 lines

  1. ;----------------------------------------------------------------------
  2. ; SKELOS32.ASM : OS/2 32-Bit Assembler Skeleton Program
  3. ; AUTHOR       : Bill Magaletta (CIS 72411,2473)
  4. ; DATE         : September 20, 1992
  5. ;
  6. ; This program has been written to TASM's IDEAL mode, and probably won't
  7. ; assemble correctly using MASM.
  8. ;
  9. ; CONDITIONS ON ENTRY                                          
  10. ;
  11. ;
  12. ;   CS  DOS       : ?
  13. ;       OS2 16-bit: Code segment selector.
  14. ;           32-bit: Code selector for the base of the address space.
  15. ;
  16. ;   SS  DOS       : Stack segment selector, except in TINY model,
  17. ;            where SS = CS.
  18. ;       OS2 16-bit: Automatic data segment selector.
  19. ;           32-bit: Data selector for the base of the address space.
  20. ;
  21. ;   DS  DOS       : PSP segment selector.
  22. ;       OS2 16-bit: Automatic data segment selector.
  23. ;           32-bit: Data selector for the base of the address space.
  24. ;
  25. ;   ES  DOS       : PSP segment selector.
  26. ;       OS2 16-bit: 0
  27. ;           32-bit: Data selector for the base of the address space.
  28. ;
  29. ;   FS  DOS       : ?
  30. ;       OS2 16-bit: ?
  31. ;           32-bit: TIB (Thread Information Block) Data Selector.
  32. ;
  33. ;   IP  DOS       : Program entry point offset.
  34. ;       OS2 16-bit: ditto
  35. ;           32-bit: ditto
  36.  
  37. ;   AX  DOS       : ?
  38. ;       OS2 16-bit: Environment segment selector. (This selector can   
  39. ;            also be obtained via DosGetEnv.)                   
  40. ;           32-bit: 0
  41. ;
  42. ;   BX  DOS       : ?                                                  
  43. ;       OS2 16-bit: Offset to program name in environment segment.     
  44. ;            (This offset can also be obtained via DosGetEnv.)  
  45. ;           32-bit: 0
  46. ;
  47. ;   CX  DOS       : ?
  48. ;       OS2 16-bit: Size of automatic data segment. Zero means 65,536. 
  49. ;           32-bit: 0
  50. ;
  51. ;   DX  DOS       : ?
  52. ;       OS2 16-bit: ?
  53. ;           32-bit: 0
  54.  
  55. ;
  56. ;   SP  DOS       :                                                    
  57. ;       OS2 16-bit: Top of stack offset.
  58. ;           32-bit: ditto
  59. ;
  60. ;             [ESP+00] : Return address; EAX should = exit code.
  61. ;             [ESP+04] : Program module handle.
  62. ;             [ESP+08] : (reserved)
  63. ;             [ESP+12] : Environment data object address.
  64. ;             [ESP+16] : Address of cmd line in env data object.
  65. ;
  66. ;
  67. ;   BP  DOS       : ?                                                  
  68. ;       OS2 16-bit: 0
  69. ;           32-bit: 0
  70. ;
  71. ;   other         : All other registers are undefined.
  72. ;
  73. ;----------------------------------------------------------------------
  74.  
  75.          IDEAL
  76.          P386
  77.          MODEL OS2 USE32 FLAT
  78.          LARGESTACK
  79.          STACK 8192H
  80.  
  81.          extrn  syscall Dos32PutMessage:near
  82.          extrn  syscall Dos32Write:near
  83.  
  84.  
  85. ;----------------------------------------------------------------------
  86. ; DATA
  87. ;----------------------------------------------------------------------
  88.  
  89.          DATASEG
  90.  
  91. Msg1     DB    13,10
  92.          DB    'OS/2 Linear Executable (32-Bit) Assembler Skeleton'
  93.          DB    ' Program',13,10
  94.          DB    'Version 1.0 ',??date,' ',??time,13,10
  95.          DB    'developed using Borland''s Turbo Assembler 3.1',13,10
  96.          DB    'by Bill Magaletta, CIS [72411,2473]',13,10
  97.          DB    13,10
  98. Msg1l    =     $-Msg1
  99.  
  100. Msg2     DB    'The title lines were displayed using Dos32PutMessage,'
  101.          DB    ' but this message',13,10
  102.          DB    'is being displayed using Dos32Write.',13,10
  103.          DB    13,10
  104.          DB    'Now let''s see your command line arguments...',13,10
  105.          DB    13,10
  106. Msg2l    =     $-Msg2
  107.  
  108. Msg98    DB    '{'
  109. Msg99    DB    '}',13,10
  110. Msg99l   =     $-Msg99
  111.  
  112. ; COMMAND LINE PARSE
  113. ARSMAX   =     2                   ;max arg strings from OS/2
  114. ARGMAX   =     16                  ;max arg strings after scan
  115. argc     DD    0                   ;no. of args
  116. argv     DQ    ARGMAX dup(?)       ;array of (offset,length)
  117.  
  118. count    dd    0
  119.          ENDS
  120.  
  121. ;----------------------------------------------------------------------
  122. ; MAIN PROGRAM
  123. ;----------------------------------------------------------------------
  124.  
  125.          CODESEG
  126.  
  127. SKELOS32:
  128.  
  129. ; Display Program Titles
  130.          CALL  Dos32PutMessage syscall,\
  131.                1,\                  stdout handle
  132.                Msg1l,\              msg length
  133.                OFFSET Msg1         ;->msg
  134.          CALL  Dos32Write syscall,\
  135.                1,\                  stdout handle
  136.                OFFSET Msg2,\        ->buffer
  137.                Msg2l,\              buffer length
  138.                OFFSET count        ;->returned length
  139.  
  140. ; Parse Command Line Arguments
  141.          CALL  CmdParse pascal,\
  142.                [dword ss:esp+16],\  ->command line
  143.                OFFSET argc,\        ->argument count
  144.                OFFSET argv         ;->argument array
  145.  
  146. ; Display Command Line Arguments
  147.          mov    ecx,[argc]
  148.          mov    esi,0
  149. ListArgs:
  150.          push   ecx
  151.          CALL   Dos32PutMessage syscall,\
  152.                 1,\
  153.                 1,\
  154.                 OFFSET Msg98
  155.          CALL   Dos32PutMessage syscall,\
  156.                 1,\
  157.                 [dword argv+esi+4],\
  158.                 [dword argv+esi]
  159.          CALL   Dos32PutMessage syscall,\
  160.                 1,\
  161.                 Msg99l,\
  162.                 OFFSET Msg99
  163.          add    esi,8
  164.          pop    ecx
  165.          loop   ListArgs
  166.  
  167.          RET
  168.  
  169.  
  170.          LOCALS
  171.  
  172. ;----------------------------------------------------------------------
  173. ; CmdParse : OS/2 Command Line Parse
  174. ;
  175. ; ARGUMENTS
  176. ;
  177. ;   @cmd :dword -> OS/2 Command Line
  178. ;
  179. ;     OS/2 command line consists of three (3) null-terminated strings:
  180. ;     program name, arguments, and null.
  181. ;
  182. ;
  183. ;   @argc:dword -> Argument Count (dword)                   (output)
  184. ;
  185. ;     Receives the number of arguments (including the program name).
  186. ;
  187. ;
  188. ;   @argv:dword -> Array of (dword->arg, dword arg length)  (output)
  189. ;
  190. ;     Receives offset and length for each argument.  Length does not
  191. ;     include the null terminator.
  192. ;
  193. ;
  194. ; LOGIC
  195. ;
  196. ; Two passes:
  197. ;
  198. ;   @@GetString - Scans the command line and produces output (argc,argv)
  199. ;     for two arguments: the program name, and the arguments string.
  200. ;
  201. ;   @@GetSubstr - Scans the arguments string (argv[1]) and breaks out
  202. ;     the individual arguments.  Initially, argv[1] describes the entire
  203. ;     arguments string.  Then, argv[1].length is set to the length of
  204. ;     1st individual argument, and argv[2] is set to describe the
  205. ;     remaining string.  This is repeated for argv[2], and so forth.
  206. ;
  207. ;----------------------------------------------------------------------
  208.  
  209.          PROC   pascal CmdParse near
  210.          ARG    @cmd:dword, @argc:dword, @argv:dword
  211.  
  212. ;----------------------------------------
  213. ; 1st Pass: Get Strings Provided by OS/2
  214. ;----------------------------------------
  215.  
  216.          mov    edi,[@cmd]         ;edi ->command line
  217.          mov    ecx,ARSMAX         ;ecx = max arg strings from OS/2
  218.          mov    esi,0              ;esi = offset to argv[current]
  219.  
  220. @@GetString:
  221.          push   ecx                ;save loop count
  222.          mov    edx,edi            ;edx ->argument string
  223.          mov    eax,0              ;eax = null terminator (scasb arg)
  224.          mov    ecx,256            ;ecx = max. scan length
  225.          cld                       ;find null terminator
  226.          repnz  scasb
  227.          sub    ecx,256            ;ecx = string length
  228.          neg    ecx
  229.          dec    ecx
  230.          mov    ebx,[@argv]        ;ebx ->argv
  231.          mov    [ebx+esi+0],edx    ;argv[esi].offset = string offset
  232.          mov    [ebx+esi+4],ecx    ;argv[esi].length = string length
  233.          add    esi,8              ;next argv element
  234.          pop    ecx                ;restore loop count
  235.          cmp    [byte es:edi],0    ;check for last arg (double null)
  236.          loopne @@GetString        ;loop 'til last arg or ARSMAX
  237.  
  238.          sub    ecx,ARSMAX         ;ecx  = number of args
  239.          neg    ecx
  240.          mov    ebx,[@argc]        ;argc = ecx
  241.          mov    [ebx],ecx
  242.          cmp    ecx,2              ;return if < 2 args
  243.          jb     @@Return
  244.  
  245. ;----------------------------------------
  246. ; 2nd Pass: Get Individual Arguments
  247. ;----------------------------------------
  248.  
  249.          mov    ebx,[@argv]        ;ebx ->argv
  250.          mov    esi,8              ;esi = offset to argv[1]
  251.          mov    ecx,ARGMAX         ;ecx = max. individual arguments
  252.          mov    edi,[ebx+esi+0]    ;edi = argv[1].offset
  253.          mov    eax,[ebx+esi+4]    ;eax = argv[1].length
  254.  
  255. @@GetSubstr:
  256.          push   ecx                ;save loop count
  257.          mov    ecx,eax            ;ecx = max. scan length
  258.          mov    eax,' '            ;eax = space (scasb arg)
  259.          cld                       ;skip leading spaces
  260.          repz   scasb
  261.          jz     @@GetSubExit       ;quit if all spaces
  262.          dec    edi                ;edi ->argument
  263.          inc    ecx                ;ecx = string length at argument
  264.          mov    [ebx+esi+0],edi    ;argv[curr].offset = edi
  265.          mov    [ebx+esi+4],ecx    ;argv[curr].length = ecx
  266.          repnz  scasb              ;find end-of-argument
  267.          mov    [ebx+esi+8],edi    ;argv[next].offset = edi
  268.          mov    [ebx+esi+12],ecx   ;argv[next].length = ecx
  269.          mov    eax,[ebx+esi+4]    ;eax = argv[curr].length - ecx
  270.          sub    eax,ecx            ;(that's the argument length if we
  271.          cmp    [byte edi-1],' '   ;didn't scan to end-of-string, but
  272.          jne    @@GetSubLen        ;it's one greater if we did.)
  273.          dec    eax
  274. @@GetSubLen:
  275.          mov    [ebx+esi+4],eax    ;argv(curr].length = eax
  276.          mov    eax,ecx            ;eax = remaining string length
  277.          add    esi,8              ;esi = offset to argv[next]
  278.          pop    ecx                ;restore loop count
  279.          cmp    [byte edi],0       ;repeat 'til end-of-string
  280.          loopne @@GetSubstr
  281.          push   ecx                ;compensating push
  282. @@GetSubExit:
  283.          pop    ecx                ;restore loop count
  284.          sub    ecx,ARGMAX         ;argc = number of args
  285.          neg    ecx
  286.          dec    ecx
  287.          mov    ebx,[@argc]
  288.          add    [ebx],ecx
  289. @@Return:
  290.          ret
  291.  
  292.          ENDP   CmdParse
  293.  
  294.          ENDS
  295.  
  296.          END   SKELOS32
  297.