I am a complete beginner to assembly language programming. I need help in writing an assembly language program to get a string from the user, count and display the number of times each word occur in the user entered string.
For example if the user types in:
Hello Hello what is new Hello what is not new
Output should be:
Hello 3
what 2
is 2
not 1
new 2
I have the following code below that will give me the frequency of characters within a string. However, I do not how to edit so that I can keep track of words instead of just characters, then be able to display those words with their corresponding frequency.
INCLUDE Irvine32.inc
Get_frequencies PROTO,
pString:PTR BYTE, ; points to string
pTable:PTR DWORD ; points to frequency table
.data
freqTable DWORD 256 DUP(0)
;aString BYTE 1,2,"This is extremely difficult for the experienced",0
aString BYTE 80 DUP(0),0
str1 BYTE "*** Constructing a Frequency Table *** (DEMO)",
0dh,0ah,0dh,0ah,
"Enter between 1 and 80 characters: ",0
.code
main PROC
call Clrscr
mov edx,OFFSET str1
call WriteString
mov ecx,SIZEOF aString - 1
mov edx,OFFSET aString
call ReadString
INVOKE Get_frequencies, ADDR aString, ADDR freqTable
call DisplayTable
exit
main ENDP
;-------------------------------------------------------------
Get_frequencies PROC,
pString:PTR BYTE, ; points to string
pTable:PTR DWORD ; points to frequencey table
;
; Constructs a character frequency table. Each array position
; is indexed by its corresponding ASCII code.
;
; Returns: Each entry in the table contains a count of how
; many times that character occurred in the string.
;-------------------------------------------------------------
mov esi,pString
mov edi,pTable
cld ; clear Direction flag (forward)
L1: mov eax,0 ; clear upper bits of EAX
lodsb ; AL = [ESI], inc ESI
cmp al,0 ; end of string?
je Exit_proc ; yes: exit
shl eax,2 ; multiply by 4
inc DWORD PTR [edi + eax] ; inc table[AL]
jmp L1 ; repeat loop
Exit_proc:
ret
Get_frequencies ENDP
;-------------------------------------------------------------
DisplayTable PROC
;
; Display the non-empty entries of the frequency table.
; This procedure was not required, but it makes it easier
; to demonstrate that Get_frequencies works.
;-------------------------------------------------------------
.data
colonStr BYTE ": ",0
.code
call Crlf
mov ecx,LENGTHOF freqTable ; entries to show
mov esi,OFFSET freqTable
mov ebx,0 ; index counter
L1: mov eax,[esi] ; get frequency count
cmp eax,0 ; count = 0?
jna L2 ; if so, skip to next entry
mov eax,ebx ; display the index
call WriteChar
mov edx,OFFSET colonStr ; display ": "
call WriteString
mov eax,[esi] ; show frequency count
call WriteDec
call Crlf
L2: add esi,TYPE freqTable ; point to next table entry
inc ebx ; increment index
loop L1
call Crlf
ret
DisplayTable ENDP
END main
This is what I have so far in my attempt to implement the brute-force search suggested in Peter's answer:
.data
str2 BYTE "one two three",0
.code
main proc
mov edi,OFFSET str2
Mov esi,edi
Mov Ecx, 0 ;reset ecx to 0
Not Ecx ;set Ecx to -1 or highest possible integer
Mov Al, ' ' ;Initialize a1 to delimiter of (space) ' '
Cld ;Clear Direction Pointer
Repne Scasb ;scan edi one byte at a time until delimiter found
Not Ecx
Lea Eax, [ecx-1] ;Set Eax to index of found delimiter
Xchg Esi, Edi ;Take Edi which is now equal to string after found delimiter and put in esi
mov edx, esi
call WriteString
main endp
end main
This prints "two three", but I want it to print "one".