home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c081_11 / 9.ddi / CHAPXMPL.ZIP / CNTWORDS.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-02-13  |  7.9 KB  |  172 lines

  1. ; Turbo Assembler    Copyright (c) 1988, 1991 By Borland International, Inc.
  2. ;
  3. ; CNTWORDS.ASM
  4. ;
  5. ; Program to count the number of words in a file.  Words are
  6. ; delimited by whitespace, which consists of spaces, tabs,
  7. ; carriage returns, and linefeeds.
  8.  
  9.  
  10.         DOSSEG                             ;select standard segment-ordering
  11.         .MODEL  SMALL                      ;code and data each fit in 64K
  12.         .STACK  200h                       ;512-byte stack
  13.         .DATA
  14. Count           DW    0                    ;used to count words
  15. InWhitespace    DB    ?                    ;set to 1 when the last
  16.                                            ; character read was whitespace
  17. TempChar        DB    ?                    ;temporary storage used by
  18.                                            ; GetNextCharacter
  19. Result          DB    'Word count: ', 5 DUP (?)
  20.                                            ;string printed to report the count
  21. CountInsertEnd  LABEL BYTE                 ;used to find the end of the area the
  22.                                            ; count value string is stored in
  23.                 DB    0dh,0ah,'$'
  24.                                            ;DOS fn #9 expects strings to end with
  25.                                            ; a dollar sign
  26.         .CODE
  27. ProgramStart:
  28.         mov     ax,@data
  29.         mov     ds,ax                      ;point DS to the .DATA segment
  30.         mov     [InWhitespace],1           ;assume we're in whitespace, since
  31.                                            ; the first non-whitespace we'll find
  32.                                            ; will mark the start of a word
  33. CountLoop:
  34.         call    GetNextCharacter           ;get next character to check
  35.         jz      CountDone                  ;...if any
  36.         call    IsCharacterWhitespace      ;is it whitespace?
  37.         jz      IsWhitespace               ;yes
  38.         cmp     [InWhitespace],0           ;character is not
  39.                                            ; whitespace-are we currently in
  40.                                            ; whitespace?
  41.         jz      CountLoop                  ;we're not in whitespace, and the
  42.                                            ; character isn't whitespace, so
  43.                                            ; we're done with this character
  44.         inc     [Count]                    ;we are in whitespace, and the
  45.                                            ; character is not whitespace, so
  46.                                            ; we just found the start of a new word
  47.         mov     [InWhitespace],0           ;mark that we're no longer in whitespace
  48.         jmp     CountLoop                  ;do the next character
  49. IsWhitespace:
  50.         mov     [InWhitespace],1           ;mark that we're in whitespace
  51.         jmp     CountLoop                  ;do the next character
  52. ;
  53. ; We're done counting--report the results.
  54. ;
  55. CountDone:
  56.         mov     ax,[Count]                 ;number to convert to a string
  57.         mov     bx,OFFSET CountInsertEnd-1 ;point to the end of the string to
  58.                                            ; put the number in
  59.         mov     cx,5                       ;number of digits to convert
  60.         call    ConvertNumberToString      ;make the number a string
  61.         mov     bx,OFFSET Result           ;point to result string
  62.         call    PrintString                ;print the count
  63.         mov     ah,4ch                     ;DOS terminate program fn #
  64.         int     21h                        ;end the program
  65. ;
  66. ; Subroutine to get the next character from the standard input.
  67. ;
  68. ; Input: None
  69. ;
  70. ; Output:
  71. ;       AL = character, if one was available
  72. ;       Z flag = 0 (NZ) if character available,
  73. ;              = 1 (Z) if end of file reached
  74. ;
  75. ; Registers destroyed: AH, BX, CX, DX
  76. ;
  77. GetNextCharacter        PROC
  78.         mov     ah,3fh                     ;DOS read from file fn #
  79.         mov     bx,0                       ;standard input handle
  80.         mov     cx,1                       ;read one character
  81.         mov     dx,OFFSET TempChar         ;put the character in TempChar
  82.         int     21h                        ;get the next character
  83.         jc      NoCharacterRead            ;if DOS reports an error, then treat
  84.                                            ; it as the end of the file
  85.         cmp     [TempChar],1ah             ;was it Control-Z?
  86.                                            ; (marks end of some files)
  87.         jne     NotControlZ                ;no
  88. NoCharacterRead:
  89.         sub     ax,ax                      ;mark no character read
  90. NotControlZ:
  91.         and     ax,ax                      ;set Z flag to reflect whether a
  92.                                            ; character was read (NZ), or the
  93.                                            ; end of the file was reached (Z).
  94.                                            ; Note that DOS fn #3fh sets AX to
  95.                                            ; the number of characters read
  96.         mov     al,[TempChar]              ;return the character read
  97.         ret                                ;done
  98. GetNextCharacter        ENDP
  99. ;
  100. ; Subroutine to report whether a given character is whitespace.
  101. ;
  102. ; Input:
  103. ;       AL = character to check
  104. ;
  105. ; Output:
  106. ;       Z flag = 0 (NZ) if character is not whitespace
  107. ;              = 1 (Z) if character is whitespace
  108. ;
  109. ; Registers destroyed: none
  110. ;
  111. IsCharacterWhitespace   PROC
  112.         cmp     al,' '                     ;is it a space?
  113.         jz      EndIsCharacterWhitespace   ;if so, it's whitespace
  114.         cmp     al,09h                     ;is it a tab?
  115.         jz      EndIsCharacterWhitespace   ;if so, it's whitespace
  116.         cmp     al,0dh                     ;is it a carriage return?
  117.         jz      EndIsCharacterWhitespace   ;if so, it's whitespace
  118.         cmp     al,0ah                     ;is it a linefeed? If so,
  119.                                            ; it's whitespace, so return Z;
  120.                                            ; if not, it's not whitespace,
  121.                                            ; so return NZ as set by cmp
  122. EndIsCharacterWhitespace:
  123.         ret
  124. IsCharacterWhitespace   ENDP
  125. ;
  126. ; Subroutine to convert a binary number to a text string.
  127. ;
  128. ; Input:
  129. ;       AX = number to convert
  130. ;       DS:BX = pointer to end of string to store text in
  131. ;       CX = number of digits to convert
  132. ;
  133. ; Output: None
  134. ;
  135. ; Registers destroyed: AX, BX, CX, DX, SI
  136. ;
  137. ConvertNumberToString   PROC
  138.         mov     si,10                      ;used to divide by 10
  139. ConvertLoop:
  140.         sub     dx,dx                      ;convert AX to doubleword in DX:AX
  141.         div     si                         ;divide number by 10. Remainder is in
  142.                                            ; DX--this is a one-digit decimal
  143.                                            ; number. Number/10 is in AX
  144.         add     dl,'0'                     ;convert remainder to a text character
  145.         mov     [bx],dl                    ;put this digit in the string
  146.         dec     bx                         ;point to the location for the
  147.                                            ; next most-significant digit
  148.         loop    ConvertLoop                ;do the next digit, if any
  149.         ret
  150. ConvertNumberToString   ENDP
  151. ;
  152. ; Subroutine to print a string on the display.
  153. ;
  154. ; Input:
  155. ;       DS:BX = pointer to string to print
  156. ;
  157. ; Output: None
  158. ;
  159. ; Registers destroyed: None
  160. ;
  161. PrintString     PROC
  162.         push    ax
  163.         push    dx                         ;preserve registers in this subroutine
  164.         mov     ah,9                       ;DOS print string function #
  165.         mov     dx,bx                      ;point DS:DX to the string to print
  166.         int     21h                        ;invoke DOS to print the string
  167.         pop     dx                         ;restore registers we changed
  168.         pop     ax
  169.         ret
  170. PrintString     ENDP
  171.         END     ProgramStart
  172.