home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / mslang / ml_os2 / skelos32.asm < prev    next >
Encoding:
Assembly Source File  |  1993-10-08  |  12.2 KB  |  368 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. ; CHANGED BY   : Manfred Rebentisch (CIS 100111,1412)
  6. ; DATE         : Oktober 8, 1993
  7. ;--------------Changes---------------------
  8. ; All changes were make to support OS/2 with MASM 6.1
  9. ; Call the compiler with the Makro _MASM_, so the Masm-Part will be compiled.
  10. ; Otherwise you can compile with TASM and define _TASM_ on command-line.
  11. ; Look for text entries "ifdef _TASM_" and ";***" to find the important 
  12. ; changes.
  13. ;------------------------------------------
  14. ;
  15. ; This program has been written to TASM's IDEAL mode, and probably won't
  16. ; assemble correctly using MASM.
  17. ;
  18. ; CONDITIONS ON ENTRY                                          
  19. ;
  20. ;
  21. ;   CS  DOS       : ?
  22. ;       OS2 16-bit: Code segment selector.
  23. ;           32-bit: Code selector for the base of the address space.
  24. ;
  25. ;   SS  DOS       : Stack segment selector, except in TINY model,
  26. ;            where SS = CS.
  27. ;       OS2 16-bit: Automatic data segment selector.
  28. ;           32-bit: Data selector for the base of the address space.
  29. ;
  30. ;   DS  DOS       : PSP segment selector.
  31. ;       OS2 16-bit: Automatic data segment selector.
  32. ;           32-bit: Data selector for the base of the address space.
  33. ;
  34. ;   ES  DOS       : PSP segment selector.
  35. ;       OS2 16-bit: 0
  36. ;           32-bit: Data selector for the base of the address space.
  37. ;
  38. ;   FS  DOS       : ?
  39. ;       OS2 16-bit: ?
  40. ;           32-bit: TIB (Thread Information Block) Data Selector.
  41. ;
  42. ;   IP  DOS       : Program entry point offset.
  43. ;       OS2 16-bit: ditto
  44. ;           32-bit: ditto
  45.  
  46. ;   AX  DOS       : ?
  47. ;       OS2 16-bit: Environment segment selector. (This selector can   
  48. ;            also be obtained via DosGetEnv.)                   
  49. ;           32-bit: 0
  50. ;
  51. ;   BX  DOS       : ?                                                  
  52. ;       OS2 16-bit: Offset to program name in environment segment.     
  53. ;            (This offset can also be obtained via DosGetEnv.)  
  54. ;           32-bit: 0
  55. ;
  56. ;   CX  DOS       : ?
  57. ;       OS2 16-bit: Size of automatic data segment. Zero means 65,536. 
  58. ;           32-bit: 0
  59. ;
  60. ;   DX  DOS       : ?
  61. ;       OS2 16-bit: ?
  62. ;           32-bit: 0
  63.  
  64. ;
  65. ;   SP  DOS       :                                                    
  66. ;       OS2 16-bit: Top of stack offset.
  67. ;           32-bit: ditto
  68. ;
  69. ;             [ESP+00] : Return address; EAX should = exit code.
  70. ;             [ESP+04] : Program module handle.
  71. ;             [ESP+08] : (reserved)
  72. ;             [ESP+12] : Environment data object address.
  73. ;             [ESP+16] : Address of cmd line in env data object.
  74. ;
  75. ;
  76. ;   BP  DOS       : ?                                                  
  77. ;       OS2 16-bit: 0
  78. ;           32-bit: 0
  79. ;
  80. ;   other         : All other registers are undefined.
  81. ;
  82. ;----------------------------------------------------------------------
  83.  
  84. ifdef _TASM_
  85.          IDEAL
  86.          P386
  87.          MODEL OS2 USE32 FLAT
  88.          LARGESTACK
  89.          STACK 8192H
  90.          extrn  syscall Dos32PutMessage:near
  91.          extrn  syscall Dos32Write:near
  92. else    ; (_MASM_)
  93. ;; [SYSCALL | STDCALL | C .. ] OS_OS2 not supported
  94.     .386P
  95.     .MODEL FLAT, PASCAL    
  96.         .STACK 8192H
  97.  
  98.     CmdParse    PROTO NEAR PASCAL, CmdLine:DWORD, Count:DWORD, Array:DWORD
  99.     Dos32PutMessage PROTO NEAR SYSCALL, usHdl:DWORD, usMsgLen:DWORD, ptrMsg:DWORD
  100.     Dos32Write PROTO NEAR SYSCALL, usHdl:DWORD, ptrMsg:DWORD, usMsgLen:DWORD, pusCount:DWORD
  101. endif
  102.  
  103. ;----------------------------------------------------------------------
  104. ; DATA
  105. ;----------------------------------------------------------------------
  106.  
  107. ifdef _TASM_
  108.          DATASEG
  109. else
  110.     .DATA
  111. endif
  112.  
  113. Msg1     DB    13,10
  114.          DB    'OS/2 Linear Executable (32-Bit) Assembler Skeleton'
  115.          DB    ' Program',13,10
  116. ifdef _TASM_
  117.          DB    'Version 2.0 ',??date,' ',??time,13,10
  118.          DB    'developed using Borland''s Turbo Assembler 3.1 [', ??Version, ']',13,10
  119. else
  120.     ; @Date, @Time and @Version don't work (why?)
  121.      DB    'Version 2.0  Okt.-08-93',13,10
  122.          DB    'developed using MS-MASM 6.1 ',13,10
  123. endif
  124.          DB    'by Bill Magaletta, CIS [72411,2473]',13,10
  125.      DB    'changed by Manfred Rebentisch, CIS [100111,1412]',13,10
  126.          DB    13,10
  127. Msg1l    =     $-Msg1
  128.  
  129. Msg2     DB    'The title lines were displayed using Dos32PutMessage,'
  130.          DB    ' but this message',13,10
  131.          DB    'is being displayed using Dos32Write.',13,10
  132.          DB    13,10
  133.          DB    'Now let''s see your command line arguments...',13,10
  134.          DB    13,10
  135. Msg2l    =     $-Msg2
  136.  
  137. Msg98    DB    '{'
  138. Msg99    DB    '}',13,10
  139. Msg99l   =     $-Msg99
  140.  
  141. ; COMMAND LINE PARSE
  142. ARSMAX   =     2                   ;max arg strings from OS/2
  143. ARGMAX   =     16                  ;max arg strings after scan
  144. argc     DD    0                   ;no. of args
  145. argv     DQ    ARGMAX dup(?)       ;array of (offset,length)
  146.  
  147. count    dd    0
  148.  
  149. @CurSeg         ENDS
  150.  
  151. ;----------------------------------------------------------------------
  152. ; MAIN PROGRAM
  153. ;----------------------------------------------------------------------
  154. ifdef _TASM_
  155.          CODESEG
  156. else
  157.     .CODE
  158. endif
  159.  
  160. SKELOS32:
  161.  
  162. ; Display Program Titles
  163. ifdef _TASM_
  164.          CALL  Dos32PutMessage syscall,\
  165.                1,\                  stdout handle
  166.                Msg1l,\              msg length
  167.                OFFSET Msg1         ;->msg
  168.          CALL  Dos32Write syscall,\
  169.                1,\                  stdout handle
  170.                OFFSET Msg2,\        ->buffer
  171.                Msg2l,\              buffer length
  172.                OFFSET count        ;->returned length
  173. else
  174.     INVOKE    Dos32PutMessage, 1, Msg1l, OFFSET Msg1
  175.     INVOKE    Dos32Write, 1, OFFSET Msg2, Msg2l, OFFSET count    
  176. endif
  177.  
  178. ; Parse Command Line Arguments
  179. ifdef _TASM_
  180.          CALL  CmdParse pascal,\
  181.                [dword ss:esp+16],\      ; ->command line
  182.                OFFSET argc,\           ; ->argument count
  183.                OFFSET argv        ;->argument array
  184. else
  185.     mov    eax, dword PTR ss:[esp+16]
  186.     INVOKE CmdParse, eax,\      ; ->command line
  187.                OFFSET argc,\           ; ->argument count
  188.                OFFSET argv        ;->argument array
  189. endif
  190.  
  191. ; Display Command Line Arguments
  192.          mov    ecx,[argc]
  193.          mov    esi,0
  194. ListArgs:
  195.          push   ecx
  196. ifdef _TASM_
  197.          CALL   Dos32PutMessage syscall,\
  198.                 1,\
  199.                 1,\
  200.                 OFFSET Msg98
  201.          CALL   Dos32PutMessage syscall,\
  202.                 1,\
  203.                 [dword argv+esi+4],\
  204.                 [dword argv+esi]
  205.          CALL   Dos32PutMessage syscall,\
  206.                 1,\
  207.                 Msg99l,\
  208.                 OFFSET Msg99
  209. else
  210.     INVOKE    Dos32PutMessage, 1, 1, OFFSET Msg98
  211.     mov    eax, [dword ptr argv+esi+4]
  212.     mov    ebx, [dword ptr argv+esi]
  213.     INVOKE    Dos32PutMessage, 1, eax, ebx
  214.     INVOKE    Dos32PutMessage, 1, Msg99l, OFFSET Msg99
  215.  
  216. endif
  217.          add    esi,8
  218.          pop    ecx
  219.          loop   ListArgs
  220.  
  221.          RET
  222.  
  223. ifdef _TASM_
  224.          LOCALS
  225. endif
  226.  
  227. ;----------------------------------------------------------------------
  228. ; CmdParse : OS/2 Command Line Parse
  229. ;
  230. ; ARGUMENTS
  231. ;
  232. ;   @cmd :dword -> OS/2 Command Line
  233. ;
  234. ;     OS/2 command line consists of three (3) null-terminated strings:
  235. ;     program name, arguments, and null.
  236. ;
  237. ;
  238. ;   @argc:dword -> Argument Count (dword)                   (output)
  239. ;
  240. ;     Receives the number of arguments (including the program name).
  241. ;
  242. ;
  243. ;   @argv:dword -> Array of (dword->arg, dword arg length)  (output)
  244. ;
  245. ;     Receives offset and length for each argument.  Length does not
  246. ;     include the null terminator.
  247. ;
  248. ;
  249. ; LOGIC
  250. ;
  251. ; Two passes:
  252. ;
  253. ;   @@GetString - Scans the command line and produces output (argc,argv)
  254. ;     for two arguments: the program name, and the arguments string.
  255. ;
  256. ;   @@GetSubstr - Scans the arguments string (argv[1]) and breaks out
  257. ;     the individual arguments.  Initially, argv[1] describes the entire
  258. ;     arguments string.  Then, argv[1].length is set to the length of
  259. ;     1st individual argument, and argv[2] is set to describe the
  260. ;     remaining string.  This is repeated for argv[2], and so forth.
  261. ;
  262. ;----------------------------------------------------------------------
  263. ifdef _TASM_
  264.          PROC   pascal CmdParse near
  265.          ARG    @cmd:dword, @argc:dword, @argv:dword
  266. else
  267. CmdParse    PROC NEAR PASCAL,
  268.       @cmd:dword, @argc:dword, @argv:dword
  269.  
  270. endif
  271.  
  272. ;----------------------------------------
  273. ; 1st Pass: Get Strings Provided by OS/2
  274. ;----------------------------------------
  275.  
  276.          mov    edi,[@cmd]         ;edi ->command line
  277.          mov    ecx,ARSMAX         ;ecx = max arg strings from OS/2
  278.          mov    esi,0              ;esi = offset to argv[current]
  279.  
  280. @@GetString:
  281.          push   ecx                ;save loop count
  282.          mov    edx,edi            ;edx ->argument string
  283.          mov    eax,0              ;eax = null terminator (scasb arg)
  284.          mov    ecx,256            ;ecx = max. scan length
  285.          cld                       ;find null terminator
  286.          repnz  scasb
  287.          sub    ecx,256            ;ecx = string length
  288.          neg    ecx
  289.          dec    ecx
  290.          mov    ebx,[@argv]        ;ebx ->argv
  291.          mov    [ebx+esi+0],edx    ;argv[esi].offset = string offset
  292.          mov    [ebx+esi+4],ecx    ;argv[esi].length = string length
  293.          add    esi,8              ;next argv element
  294.          pop    ecx                ;restore loop count
  295. ;*** 
  296. ; TASM accept the use of ES here, but not MASM:
  297. ;         cmp    [byte es:edi], 0    ;check for last arg (double null)
  298. ;
  299.     cmp    byte ptr [edi], 0
  300.          loopne @@GetString        ;loop 'til last arg or ARSMAX
  301.  
  302.          sub    ecx,ARSMAX         ;ecx  = number of args
  303.          neg    ecx
  304.          mov    ebx,[@argc]        ;argc = ecx
  305.          mov    [ebx],ecx
  306.          cmp    ecx,2              ;return if < 2 args
  307.          jb     @@Return
  308.  
  309. ;----------------------------------------
  310. ; 2nd Pass: Get Individual Arguments
  311. ;----------------------------------------
  312.  
  313.          mov    ebx,[@argv]        ;ebx ->argv
  314.          mov    esi,8              ;esi = offset to argv[1]
  315.          mov    ecx,ARGMAX         ;ecx = max. individual arguments
  316.          mov    edi,[ebx+esi+0]    ;edi = argv[1].offset
  317.          mov    eax,[ebx+esi+4]    ;eax = argv[1].length
  318.  
  319. @@GetSubstr:
  320.          push   ecx                ;save loop count
  321.          mov    ecx,eax            ;ecx = max. scan length
  322.          mov    eax,' '            ;eax = space (scasb arg)
  323.          cld                       ;skip leading spaces
  324.          repz   scasb
  325.          jz     @@GetSubExit       ;quit if all spaces
  326.          dec    edi                ;edi ->argument
  327.          inc    ecx                ;ecx = string length at argument
  328.          mov    [ebx+esi+0],edi    ;argv[curr].offset = edi
  329.          mov    [ebx+esi+4],ecx    ;argv[curr].length = ecx
  330.          repnz  scasb              ;find end-of-argument
  331.          mov    [ebx+esi+8],edi    ;argv[next].offset = edi
  332.          mov    [ebx+esi+12],ecx   ;argv[next].length = ecx
  333.          mov    eax,[ebx+esi+4]    ;eax = argv[curr].length - ecx
  334.          sub    eax,ecx            ;(that's the argument length if we
  335. ;***
  336. ; MASM need 'byte ptr' instead of 'byte':
  337. ;
  338.          cmp    byte ptr [edi-1],' '   ;didn't scan to end-of-string, but
  339.          jne    @@GetSubLen        ;it's one greater if we did.)
  340.          dec    eax
  341. @@GetSubLen:
  342.          mov    [ebx+esi+4],eax    ;argv(curr].length = eax
  343.          mov    eax,ecx            ;eax = remaining string length
  344.          add    esi,8              ;esi = offset to argv[next]
  345.          pop    ecx                ;restore loop count
  346. ;***
  347.          cmp    BYTE PTR [edi],0               ;repeat 'til end-of-string
  348.          loopne @@GetSubstr
  349.          push   ecx                ;compensating push
  350. @@GetSubExit:
  351.          pop    ecx                ;restore loop count
  352.          sub    ecx,ARGMAX         ;argc = number of args
  353.          neg    ecx
  354.          dec    ecx
  355.          mov    ebx,[@argc]
  356.          add    [ebx],ecx
  357. @@Return:
  358.          ret
  359. ifdef _TASM_
  360.          ENDP   CmdParse
  361. else
  362. CmdParse    ENDP
  363. endif
  364.  
  365. @CurSeg         ENDS
  366.  
  367.          END   SKELOS32
  368.