I have a script that is almost done. I am struggling to finish the word counter. In this case I am counting each instance of a space and assuming that means it is the end of a word.
The 'totalWords' variable is initialized to 0 and incremented each time a ' ' is found in a string.
However, the output is always '+0' whenever tested. I know the rest of the script works because it transforms the case of the letters successfully.
What is the best practice to increment a variable and display it?
INCLUDE Irvine32.inc
.data
source BYTE 40 DUP (0)
byteCount DWORD ?
target BYTE SIZEOF source DUP('#')
sentencePrompt BYTE "Please enter a sentence: ",0
wordCountPrompt BYTE "The number of words in the input string is: ",0
outputStringPrompt BYTE "The output string is: ",0
totalWords DWORD 0 ; SET TOTALWORDS VARIABLE TO 0 INITIALLY
one DWORD 1
space BYTE " ",0
.code
main PROC
mov edx, OFFSET sentencePrompt
call Crlf
call WriteString
mov edx, OFFSET source
MOV ecx, SIZEOF source
call ReadString
call Crlf
call Crlf
call TRANSFORM_STRING
call Crlf
exit
main ENDP
TRANSFORM_STRING PROC
mov esi,0
mov edi,0
mov ecx, SIZEOF source
transformStringLoop:
mov al, source[esi]
.IF(al == space)
inc totalWords ; INCREMENT TOTALWORDS DATA
mov target[edi], al
inc esi
inc edi
.ELSE
.IF(al >= 64) && (al <=90)
add al,32
mov target[edi], al
inc esi
inc edi
.ELSEIF (al >= 97) && (al <=122)
sub al,32
mov target[edi], al
inc esi
inc edi
.ELSE
mov target[edi], al
inc esi
inc edi
.ENDIF
.ENDIF
loop transformStringLoop
mov edx, OFFSET wordCountPrompt
call WriteString
mov edx, OFFSET totalWords ; DISPLAY TOTALWORDS
call WriteInt
call Crlf
mov edx, OFFSET outputStringPrompt
call WriteString
mov edx, OFFSET target
call WriteString
ret
TRANSFORM_STRING ENDP
END main
This part is incorrect:
mov edx, OFFSET totalWords ; DISPLAY TOTALWORDS
call WriteInt
WriteInt
doesn't expect an offset in edx
; it expects the actual integer value in eax
. So the code should be:
mov eax, totalWords ; DISPLAY TOTALWORDS
call WriteInt
Also, your space variable is pointless. You could just write
.IF(al == ' ')
And your way of counting the number of words sounds a bit broken. A string such as "foo bar"
contains only 1 space, but two words. Note that you can't really use number_of_spaces+1
either, because that would give the wrong result for strings like " "
, "foo bar"
and "foo "
.
You'd probably get better results with something like:
if (al != ' ' && (esi == 0 || source[esi-1] == ' ')) totalWords++;
That's just some pseudo-code to express the idea. I'll leave it up to you to translate that into x86 assembly.