home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Stars of Shareware: Programmierung
/
SOURCE.mdf
/
programm
/
msdos
/
asm
/
ucrstdlb
/
ts.asm
< prev
next >
Wrap
Assembly Source File
|
1991-10-13
|
7KB
|
377 lines
;****************************************************************************
;
; TS: A "Text Statistics" package which demonstrates the use of the UCR
; Standard Library Package.
;
; Note: The purpose of this program is not to demonstrate blazing fast
; assembly code (it's not particularly fast) but rather to demonstrate
; how easy it is to write assembly code using the standard library
; and MASM 6.0.
;
; Randall Hyde
; 10/2/91
;
;***************************************************************************
;
; The following include must be outside any segment and before the
; ZZZZZZSEG segment. It includes all the macro definitions for the
; UCR Standard Library.
;
include stdlib.a ;Links into the UCR Standard
includelib stdlib.lib ; Library package.
;
;
dseg segment para public 'data'
;
WordCount dw 0
LineCnt dw 0
ControlCnt dw 0
FileHandle dw 0
Punct dw 0
Other dw 0
AlphaCnt dw 0
NumericCnt dw 0
MemorySize dw 0
Chars dw 0
TotalChars dq 0.0
Const100 dq 100.0
;
;
; Create some sets to use in this program:
;
set CharSet,Alphabetic,Punctuation,Control
;
;
; Character Counter:
;
CharCnt db 256 dup (0)
;
; Boolean flag to denote in/not in a word:
;
InWord db 0
;
dseg ends
;
;
cseg segment para public 'code'
assume cs:cseg, ds:dseg
;
;
; LESI is a macro which loads a 32-bit immediate value into ES:DI.
;
lesi macro adrs
mov di, seg adrs
mov es, di
lea di, adrs
endm
;
; ldxi loads a 32-bit immediate value into dx:si:
;
ldxi macro adrs
mov dx, seg adrs
lea si, adrs
endm
;
;
;
;
; Some useful constants-
;
cr equ 13
lf equ 10
EOFError equ 8
;
;
public PSP ;DOS Program Segment Prefix
PSP dw ? ;Needed by StdLib MemInit routine
;
;
; Okay, here's the main program which does the job:
;
TS proc
mov cs:PSP, es ;Save pgm seg prefix
mov ax, seg dseg ;Set up the segment registers
mov ds, ax
mov es, ax
;
; Initialize the memory manager, giving all free memory to the heap.
;
mov dx, 0
meminit
mov MemorySize, cx ;Save # of available paragraphs.
;
; Set up the character sets:
;
; First, build the Alphabetic set:
;
mov al, "A"
mov ah, "Z"
lesi Alphabetic
RangeSet
AddStrL
db "abcdefghijklmnopqrstuvwxyz",0
;
; Create the set with the punctuation characters:
;
lesi Punctuation
AddStrL
db "!@#$%^&*()_-+={[}]|\':;<,>.?/~`", '"', 0
;
; Create the control character set:
;
lesi Control
mov al,0
mov ah, 1fh
RangeSet
mov al, 7fh
AddChar
;
;
; Print the amount of available memory and prompt the user to enter a file name.
;
printf
db "Text Statistics Program",cr,lf
db "There are %d paragraphs of memory available",cr,lf
db lf
db "Enter a filename:",0
dd MemorySize
;
getsm ;Get the filename.
;
; Open the file.
;
mov al, 0 ;Open for reading.
fopen ;Open the file.
jnc GoodOpen
;
; If the carry flag comes back set, we've got an error, print an appropriate
; message and quit:
;
print
db "DOS error #",0
puti ;Error code is in AX.
putcr
jmp Return2DOS
;
; If the carry flag comes back clear, we've successfully opened the file.
; AX contains the STDLIB filehandle, ES:DI still points at the filename
; allocated on the heap:
;
GoodOpen: mov FileHandle, AX ;Save STDLIB file handle.
print
db "Computing text statistics for ",0
puts ;Print filename
free ;Dispose of space on heap
putcr
putcr
;
; The following loops check for transitions between words and delimiters.
; Each time we go from "not a word" -> "word" this code bumps up the word
; count by one.
;
mov ax, FileHandle
fReadOn
;
TSLoop: getc
jnc NoError
jmp ReadError
;
; See if the character is alphabetic
;
NoError: lesi Alphabetic
Member
jnz NotAlphabetic
inc AlphaCnt
jmp StatDone
;
; See if the character is a digit:
;
NotAlphabetic: cmp al, "0"
jb NotNumeric
cmp al, "9"
ja NotNumeric
inc NumericCnt
jmp StatDone
;
; See if the character is a punctuation character
;
NotNumeric: lesi Punctuation
Member
jnz NotPunctuation
inc Punct
jmp StatDone
;
; See if this is a control character:
;
NotPunctuation: lesi Control
Member
jnz NotControl
inc ControlCnt
jmp StatDone
;
NotControl: inc Other
StatDone: mov bl, al
mov bh, 0
inc CharCnt [bx]
;
; Count lines and characters here:
;
cmp al, lf
jne NotNewLine
inc LineCnt
;
NotNewLine: inc Chars
;
; Count words down here
;
cmp InWord, 0 ;See if we're in a word.
je NotInAWord
cmp al, " "
ja WCDone
mov InWord, 0 ;Just left a word
jmp WCDone
;
NotInAWord: cmp al, " "
jbe WCDone
mov InWord, 1 ;Just entered a word
inc WordCount
;
WCDone:
;
; Okay, or the current character into the character set:
;
lesi CharSet
AddChar
jmp TSLoop
;
;
; Come down here on EOF or other read error.
;
ReadError: cmp ax, EOFError
je Quit
print
db "DOS Error ",0
puti
putcr
jmp Return2DOS
;
; Return to DOS.
;
Quit: freadoff
mov ax, FileHandle
fclose
printf
db cr,lf,lf
db "Number of words in this file is %d",cr,lf
db "Number of lines in this file is %d",cr,lf
db "Number of control characters is %d",cr,lf
db "Number of punctuation characters is %d",cr,lf
db "Number of alphabetic characters is %d",cr,lf
db "Number of numeric character is %d",cr,lf
db "Number of other characters is %d",cr,lf
db "Total number of characters is %d",cr,lf
db lf, 0
dd WordCount,LineCnt,ControlCnt,Punct
dd AlphaCnt,NumericCnt,Other,Chars
;
; Print the characters that actually appeared in the file.
;
lesi CharSet
EC64: mov cx, 64 ;Chars/line on output.
EachChar: RmvItem
cmp al, 0
je CSDone
cmp al, " "
jbe EachChar
putc
loop EachChar
putcr
jmp EC64
;
CSDone: print
db cr,lf,lf
db "Press any key to continue:",0
getc
putcr
putcr
;
; Now print the statistics for each character:
;
mov ax, Chars ;Get character count,
utof ; convert it to a floating
lesi TotalChars ; point value, and save this
sdfpa ; value in "TotalChars".
;
public ComputeRatios
mov bx, " "
ComputeRatios:: mov al, CharCnt[bx]
mov ah, 0
cmp al, ah
je SkipThisChar
mov al, bl
putc
print
db " = ",0
mov al, CharCnt [bx]
mov cx, 4
putisize
print
db " Percentage of total is ",0
;
utof
;
; Divide by the total number of characters in the file:
;
lesi TotalChars
ldfpo
fpdiv
;
; Multiply by 100 to get a percentage
;
lesi Const100
ldfpo
fpmul
;
; Print the ratio:
;
mov al, 7
mov ah, 2
ftoam
puts
free
print
db "%",cr,lf,0
;
SkipThisChar: inc bx
cmp bx, 100h
jb ComputeRatios
putcr
;
Return2DOS: mov ah, 4ch
int 21h
;
;
TS endp
;
;
;
cseg ends
;
;
; Allocate a reasonable amount of space for the stack (2k).
;
sseg segment para stack 'stack'
stk db 256 dup ("stack ")
sseg ends
;
;
;
; zzzzzzseg must be the last segment that gets loaded into memory!
; The UCR Standard Library package uses this segment to determine where
; the end of the program lies.
;
zzzzzzseg segment para public 'zzzzzz'
LastBytes db 16 dup (?)
zzzzzzseg ends
end TS