home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / asm / ucrstdlb / ts.asm < prev    next >
Assembly Source File  |  1991-10-13  |  7KB  |  377 lines

  1. ;****************************************************************************
  2. ;
  3. ; TS:     A "Text Statistics" package which demonstrates the use of the UCR
  4. ;    Standard Library Package.
  5. ;
  6. ; Note:    The purpose of this program is not to demonstrate blazing fast
  7. ;    assembly code (it's not particularly fast) but rather to demonstrate
  8. ;    how easy it is to write assembly code using the standard library
  9. ;    and MASM 6.0.
  10. ;
  11. ; Randall Hyde
  12. ; 10/2/91
  13. ;
  14. ;***************************************************************************
  15. ;
  16. ;  The following include must be outside any segment and before the
  17. ;  ZZZZZZSEG segment.  It includes all the macro definitions for the
  18. ;  UCR Standard Library.
  19. ;
  20.         include     stdlib.a    ;Links into the UCR Standard
  21.         includelib    stdlib.lib    ; Library package.
  22. ;
  23. ;
  24. dseg        segment    para public 'data'
  25. ;
  26. WordCount    dw    0
  27. LineCnt        dw    0
  28. ControlCnt    dw    0
  29. FileHandle    dw    0
  30. Punct        dw      0
  31. Other        dw    0
  32. AlphaCnt    dw    0
  33. NumericCnt    dw    0
  34. MemorySize    dw    0
  35. Chars        dw    0
  36. TotalChars    dq    0.0
  37. Const100    dq    100.0
  38. ;
  39. ;
  40. ; Create some sets to use in this program:
  41. ;
  42.         set    CharSet,Alphabetic,Punctuation,Control
  43. ;
  44. ;
  45. ; Character Counter:
  46. ;
  47. CharCnt        db    256 dup (0)
  48. ;
  49. ; Boolean flag to denote in/not in a word:
  50. ;
  51. InWord        db    0
  52. ;
  53. dseg        ends
  54. ;
  55. ;
  56. cseg        segment    para public 'code'
  57.         assume    cs:cseg, ds:dseg
  58. ;
  59. ;
  60. ; LESI is a macro which loads a 32-bit immediate value into ES:DI.
  61. ;
  62. lesi        macro    adrs
  63.         mov     di, seg adrs
  64.         mov    es, di
  65.         lea    di, adrs
  66.         endm
  67. ;
  68. ; ldxi loads a 32-bit immediate value into dx:si:
  69. ;
  70. ldxi        macro    adrs
  71.         mov     dx, seg adrs
  72.         lea    si, adrs
  73.         endm
  74. ;
  75. ;
  76. ;
  77. ;
  78. ; Some useful constants-
  79. ;
  80. cr        equ    13
  81. lf        equ    10
  82. EOFError    equ    8
  83. ;
  84. ;
  85.         public    PSP        ;DOS Program Segment Prefix
  86. PSP        dw    ?        ;Needed by StdLib MemInit routine
  87. ;
  88. ;
  89. ; Okay, here's the main program which does the job:
  90. ;
  91. TS        proc
  92.         mov    cs:PSP, es        ;Save pgm seg prefix
  93.         mov    ax, seg dseg        ;Set up the segment registers
  94.         mov    ds, ax
  95.         mov    es, ax
  96. ;
  97. ; Initialize the memory manager, giving all free memory to the heap.
  98. ;
  99.         mov    dx, 0
  100.         meminit
  101.         mov    MemorySize, cx        ;Save # of available paragraphs.
  102. ;
  103. ; Set up the character sets:
  104. ;
  105. ;  First, build the Alphabetic set:
  106. ;
  107.         mov    al, "A"
  108.         mov    ah, "Z"
  109.         lesi    Alphabetic
  110.         RangeSet
  111.         AddStrL
  112.         db    "abcdefghijklmnopqrstuvwxyz",0
  113. ;
  114. ; Create the set with the punctuation characters:
  115. ;
  116.         lesi    Punctuation
  117.         AddStrL
  118.         db    "!@#$%^&*()_-+={[}]|\':;<,>.?/~`", '"', 0
  119. ;
  120. ; Create the control character set:
  121. ;
  122.         lesi    Control
  123.         mov    al,0
  124.         mov    ah, 1fh
  125.         RangeSet
  126.         mov    al, 7fh
  127.         AddChar
  128. ;
  129. ;
  130. ; Print the amount of available memory and prompt the user to enter a file name.
  131. ;
  132.         printf
  133.         db    "Text Statistics Program",cr,lf
  134.         db    "There are %d paragraphs of memory available",cr,lf
  135.         db    lf
  136.         db    "Enter a filename:",0
  137.         dd    MemorySize
  138. ;
  139.         getsm                ;Get the filename.
  140. ;
  141. ; Open the file.
  142. ;
  143.         mov    al, 0            ;Open for reading.
  144.         fopen                ;Open the file.
  145.         jnc    GoodOpen
  146. ;
  147. ; If the carry flag comes back set, we've got an error, print an appropriate
  148. ; message and quit:
  149. ;
  150.         print
  151.         db    "DOS error #",0
  152.         puti                ;Error code is in AX.
  153.         putcr
  154.         jmp    Return2DOS
  155. ;
  156. ; If the carry flag comes back clear, we've successfully opened the file.
  157. ; AX contains the STDLIB filehandle, ES:DI still points at the filename
  158. ; allocated on the heap:
  159. ;
  160. GoodOpen:    mov    FileHandle, AX        ;Save STDLIB file handle.
  161.         print
  162.         db    "Computing text statistics for ",0
  163.         puts                ;Print filename
  164.         free                ;Dispose of space on heap
  165.         putcr
  166.         putcr
  167. ;
  168. ; The following loops check for transitions between words and delimiters.
  169. ; Each time we go from "not a word" -> "word" this code bumps up the word
  170. ; count by one.
  171. ;
  172.         mov    ax, FileHandle
  173.         fReadOn
  174. ;
  175. TSLoop:        getc
  176.         jnc    NoError
  177.         jmp    ReadError
  178. ;
  179. ; See if the character is alphabetic
  180. ;
  181. NoError:    lesi    Alphabetic
  182.         Member
  183.         jnz    NotAlphabetic
  184.         inc    AlphaCnt
  185.         jmp    StatDone
  186. ;
  187. ; See if the character is a digit:
  188. ;
  189. NotAlphabetic:    cmp    al, "0"
  190.         jb    NotNumeric
  191.         cmp    al, "9"
  192.         ja    NotNumeric
  193.         inc    NumericCnt
  194.         jmp    StatDone
  195. ;
  196. ; See if the character is a punctuation character
  197. ;
  198. NotNumeric:    lesi    Punctuation
  199.         Member
  200.         jnz    NotPunctuation
  201.         inc    Punct
  202.         jmp    StatDone
  203. ;
  204. ; See if this is a control character:
  205. ;
  206. NotPunctuation:    lesi    Control
  207.         Member
  208.         jnz    NotControl
  209.         inc    ControlCnt
  210.         jmp    StatDone
  211. ;
  212. NotControl:    inc    Other
  213. StatDone:       mov    bl, al
  214.         mov    bh, 0
  215.         inc    CharCnt [bx]
  216. ;
  217. ; Count lines and characters here:
  218. ;
  219.         cmp    al, lf
  220.         jne    NotNewLine
  221.         inc    LineCnt
  222. ;
  223. NotNewLine:     inc    Chars
  224. ;
  225. ; Count words down here
  226. ;
  227.         cmp    InWord, 0        ;See if we're in a word.
  228.         je    NotInAWord
  229.         cmp    al, " "
  230.         ja    WCDone
  231.         mov    InWord, 0        ;Just left a word
  232.         jmp    WCDone
  233. ;
  234. NotInAWord:    cmp    al, " "
  235.         jbe    WCDone
  236.         mov    InWord, 1        ;Just entered a word
  237.         inc    WordCount
  238. ;
  239. WCDone:
  240. ;
  241. ; Okay, or the current character into the character set:
  242. ;
  243.         lesi    CharSet
  244.         AddChar
  245.         jmp    TSLoop
  246. ;
  247. ;
  248. ; Come down here on EOF or other read error.
  249. ;
  250. ReadError:    cmp    ax, EOFError
  251.         je    Quit
  252.         print
  253.         db    "DOS Error ",0
  254.         puti
  255.         putcr
  256.         jmp    Return2DOS
  257. ;
  258. ; Return to DOS.
  259. ;
  260. Quit:        freadoff
  261.         mov    ax, FileHandle
  262.         fclose
  263.         printf
  264.         db    cr,lf,lf
  265.         db    "Number of words in this file is %d",cr,lf
  266.         db    "Number of lines in this file is %d",cr,lf
  267.         db    "Number of control characters is %d",cr,lf
  268.         db    "Number of punctuation characters is %d",cr,lf
  269.         db    "Number of alphabetic characters is %d",cr,lf
  270.         db    "Number of numeric character is %d",cr,lf
  271.         db    "Number of other characters is %d",cr,lf
  272.         db    "Total number of characters is %d",cr,lf
  273.         db    lf, 0
  274.         dd    WordCount,LineCnt,ControlCnt,Punct
  275.         dd    AlphaCnt,NumericCnt,Other,Chars
  276. ;
  277. ; Print the characters that actually appeared in the file.
  278. ;
  279.         lesi    CharSet
  280. EC64:        mov    cx, 64            ;Chars/line on output.
  281. EachChar:    RmvItem
  282.         cmp    al, 0
  283.         je    CSDone
  284.         cmp    al, " "
  285.         jbe    EachChar
  286.         putc
  287.         loop    EachChar
  288.         putcr
  289.         jmp    EC64
  290. ;
  291. CSDone:        print
  292.         db    cr,lf,lf
  293.         db    "Press any key to continue:",0
  294.         getc
  295.         putcr
  296.         putcr
  297. ;
  298. ; Now print the statistics for each character:
  299. ;
  300.         mov    ax, Chars        ;Get character count,
  301.         utof                ; convert it to a floating
  302.         lesi    TotalChars        ; point value, and save this
  303.         sdfpa                ; value in "TotalChars".
  304. ;
  305.         public    ComputeRatios
  306.         mov    bx, " "
  307. ComputeRatios::    mov    al, CharCnt[bx]
  308.         mov    ah, 0
  309.         cmp    al, ah
  310.         je    SkipThisChar
  311.         mov    al, bl
  312.         putc
  313.         print
  314.         db    " = ",0
  315.         mov    al, CharCnt [bx]
  316.         mov    cx, 4
  317.         putisize
  318.         print
  319.         db    "  Percentage of total is ",0
  320. ;
  321.         utof
  322. ;
  323. ; Divide by the total number of characters in the file:
  324. ;
  325.         lesi    TotalChars
  326.         ldfpo
  327.         fpdiv
  328. ;
  329. ; Multiply by 100 to get a percentage
  330. ;
  331.         lesi    Const100
  332.         ldfpo
  333.         fpmul
  334. ;
  335. ; Print the ratio:
  336. ;
  337.         mov    al, 7
  338.         mov    ah, 2
  339.         ftoam
  340.         puts
  341.         free
  342.         print
  343.         db    "%",cr,lf,0
  344. ;
  345. SkipThisChar:    inc    bx
  346.         cmp    bx, 100h
  347.         jb      ComputeRatios
  348.         putcr
  349. ;
  350. Return2DOS:    mov     ah, 4ch
  351.         int     21h
  352. ;
  353. ;
  354. TS        endp
  355. ;
  356. ;
  357. ;
  358. cseg            ends
  359. ;
  360. ;
  361. ; Allocate a reasonable amount of space for the stack (2k).
  362. ;
  363. sseg        segment    para stack 'stack'
  364. stk        db    256 dup ("stack   ")
  365. sseg        ends
  366. ;
  367. ;
  368. ;
  369. ; zzzzzzseg must be the last segment that gets loaded into memory!
  370. ; The UCR Standard Library package uses this segment to determine where
  371. ; the end of the program lies.
  372. ;
  373. zzzzzzseg    segment    para public 'zzzzzz'
  374. LastBytes    db    16 dup (?)
  375. zzzzzzseg    ends
  376.         end    TS
  377.