My program seems to be stuck in a loop after the program prompts the user to input the paragraph.
TITLE CSC221A4 (CSC2214.asm)
INCLUDE Irvine32.inc
.data
mainMenu1 BYTE " ", 0Ah, 0Ah, 0Ah
BYTE " Main Menu ", 0Ah
BYTE " 1. Count and Display number of characters (Press 1) ", 0Ah, 0Ah
BYTE " 2. Count and display number of words (Press 2) ", 0Ah, 0Ah
BYTE " 3. Count and display number of sentences (Press 3) ", 0Ah, 0Ah
BYTE " 4. Count and display numbers of letters that are equal to 'N' or 'n' (Press 4)", 0Ah, 0Ah
BYTE " 5. Count and display number of capital letters (Press 5) ", 0Ah, 0Ah
BYTE " 6. Count and display number of vowels (Press 6) ", 0Ah, 0Ah
prompt1 BYTE " ", 0Ah, 0Ah
BYTE "Please enter your paragraph. Press $ to end.",0Ah, 0Ah, 0
prompt2 BYTE " ", 0Ah, 0Ah
BYTE " '$' was entered. Paragraph will now calculate.", 0Ah, 0Ah, 0
prompt3 BYTE "Calculating choice ", 0Ah, 0Ah, 0
prompt4 BYTE "Number of characters: ",0
prompt5 BYTE "Number of words: ",0
prompt6 BYTE "Number of sentences: ",0
prompt7 BYTE "Number of letters equal to 'N' or 'n': ",0
prompt8 BYTE "Number of capital letters: ",0
prompt9 BYTE "Number of vowels: ",0
Sentinel BYTE '$'
thirdLetter BYTE 'N' , 'n'
space BYTE ' '
num_char DWORD ?
num_words DWORD ?
num_sentences DWORD ?
num_thirdLetter DWORD ?
num_capLetter DWORD ?
num_vowels DWORD ?
.code
main PROC
call mainMenu
exit
main ENDP
mainMenu PROC
mov edx, OFFSET mainMenu1
call WriteString
mov eax, 0;
call ReadChar
cmp al, '1'
jne JUMPLABEL1
call Option1
JUMPLABEL1:
cmp al, '2'
jne JUMPLABEL2
call Option2
JUMPLABEL2:
cmp al, '3'
jne JUMPLABEL3
call option3
JUMPLABEL3:
cmp al, '4'
jne JUMPLABEL4
call option4
JUMPLABEL4:
cmp al, '5'
jne JUMPLABEL5
call option5
JUMPLABEL5:
cmp al, '6'
call option6
exit
mainMenu ENDP
Option1 PROC
mov edx, OFFSET prompt1
call WriteString
mov eax, 0
mov num_char, 1
mov num_words, 1
mov num_sentences, 1
mov num_thirdLetter, 1
mov num_capLetter, 1
mov num_vowels, 1
L1:
call ReadChar
call WriteTempOutput
cmp al, Sentinel
jne Not_Sentinel_Flag
mov edx, OFFSET prompt2
call WriteString
jmp End_Flag
Not_Sentinel_Flag:
cmp al, space
jne Not_New_Char_Flag
inc num_char
Not_New_Char_Flag:
cmp al, 0dh
jne Not_New_Line_Flag
inc num_char
Not_New_Line_Flag:
jmp L1;
End_Flag:
call Display_Char_Results
Option1 ENDP
Option2 PROC
mov edx, OFFSET prompt1
call WriteString
mov num_words, 1
mov num_sentences, 1
mov num_thirdLetter, 1
mov num_capLetter, 1
mov num_vowels, 1
L1:
call ReadChar
Call WriteTempOutput
cmp al, sentinel
jne Not_Sentinel_Flag
mov edx, OFFSET prompt2
call writestring
jmp End_Flag
Not_Sentinel_Flag:
cmp al, space
jne NOT_NEW_WORD_FLAG
inc num_words
NOT_NEW_WORD_FLAG:
cmp al, 0dh
jne Not_New_Line_Flag
inc num_words
Not_New_Line_Flag:
jmp L1;
End_Flag:
call Display_Word_Results
Option2 ENDP
option3 PROC
mov edx, OFFSET prompt1
call WriteString
mov num_capLetter, 1
mov num_char, 1
mov num_sentences, 1
mov num_thirdLetter, 1
mov num_vowels, 1
mov num_words, 1
L1:
call ReadChar
call WriteTempOutput
cmp al, sentinel
jne Not_Sentinel_Flag
mov edx, OFFSET prompt2
call writestring
jmp End_Flag
Not_Sentinel_Flag:
cmp al, 0dh
jne Not_New_Line_Flag
inc num_sentences
Not_New_Line_Flag:
jmp L1;
End_Flag:
call Display_Sentences_Results
option3 ENDP
option4 PROC
mov edx, OFFSET prompt1
call WriteString
mov num_capLetter, 1
mov num_char, 1
mov num_sentences, 1
mov num_thirdLetter, 1
mov num_vowels, 1
mov num_words, 1
L1:
call readchar
call WriteTempOutput
cmp al, sentinel
jne Not_Sentinel_Flag
mov edx, OFFSET prompt2
call writestring
jmp End_Flag
Not_Sentinel_Flag:
cmp al, 'N'
jne Not_Uppercase_N
inc num_thirdLetter
Not_Uppercase_N:
cmp al, 'n'
jne Not_Letter_N_flag
inc num_thirdLetter
Not_Letter_N_flag:
jmp L1;
End_Flag:
call Display_thirdLetter_results
option4 ENDP
option5 PROC
mov edx, OFFSET prompt1
call writestring
mov num_capLetter, 1
mov num_char, 1
mov num_sentences, 1
mov num_thirdLetter, 1
mov num_vowels, 1
mov num_words, 1
L1:
call readchar
call WriteTempOutput
cmp al, sentinel
jne Not_Sentinel_Flag
mov edx, OFFSET prompt2
call writestring
jmp End_Flag
Not_Sentinel_Flag:
cmp al, 'A' - 'Z'
jbe NOT_Capital_letter
inc num_capLetter
NOT_Capital_letter:
jmp L1;
End_Flag:
call Display_capital_results
option5 ENDP
option6 PROC
mov edx, OFFSET prompt1
call writestring
mov num_capLetter, 1
mov num_char, 1
mov num_sentences, 1
mov num_thirdLetter, 1
mov num_vowels, 1
mov num_words, 1
L1:
call readchar
call WriteTempOutput
cmp al, sentinel
mov edx, OFFSET prompt2
call writestring
OPTION6 endp
Display_char_results PROC
mov edx, OFFSET prompt3
call writestring
mov edx, OFFSET prompt4
call writestring
mov eax, 0
mov eax, num_char
call WriteDec
call crlf
call mainMenu
Display_char_results ENDP
DISPLAY_WORD_RESULTS PROC
mov edx,OFFSET prompt3
call WriteString
mov edx,OFFSET prompt5
call WriteString
mov eax,0
mov eax,num_words
call writeDec
call CRLF
call mainMenu
DISPLAY_WORD_RESULTS ENDP
DISPLAY_sentences_RESULTS PROC
mov edx,OFFSET prompt3
call WriteString
mov edx,OFFSET prompt6
call WriteString
mov eax,0
mov eax,num_sentences
call writeDec
call CRLF
call mainMenu
DISPLAY_sentences_RESULTS ENDP
DISPLAY_thirdLetter_results PROC
mov edx,OFFSET prompt3
call WriteString
mov edx,OFFSET prompt7
call WriteString
mov eax,0
mov eax,num_thirdLetter
call writeDec
call CRLF
call mainMenu
DISPLAY_thirdLetter_rESULTS ENDP
Display_capital_results PROC
mov edx, OFFSET prompt3
call writestring
mov edx, OFFSET prompt8
call writestring
mov eax, 0
mov eax, num_capLetter
call writeDec
call crlf
call mainMenu
Display_capital_results ENDP
Display_vowels_results PROC
mov edx, OFFSET prompt3
call writestring
mov edx, OFFSET prompt9
call writestring
mov eax, 0
mov eax, num_vowels
call writeDec
call crlf
call mainMenu
Display_vowels_results ENDP
WriteTempOutput PROC
cmp AL,0Dh
jne NONEWLINE
mov BL,AL
mov AL,0Ah
call WriteChar
mov AL,BL
call WriteChar
ret
NONEWLINE:
call dumpregs
call WriteChar
ret
WriteTempOutput ENDP
exit
END main
Your program mostly has issues with its flow. When we use the call
instruction we expect to return here. But your code just screams to jmp
so that's the instruction you should use to correct the problems.
cmp al, '1'
jne JUMPLABEL1
call Option1 <-- Change this to jmp Option1
JUMPLABEL1:
Every time that you have a block of code like the previous you should not CALL but rather JUMP to the relevant Option_ procedure.
...
L1:
call ReadChar
call WriteTempOutput
cmp al, Sentinel
jne Not_Sentinel_Flag
mov edx, OFFSET prompt2
call WriteString
jmp End_Flag
Not_Sentinel_Flag:
cmp al, space
jne Not_New_Char_Flag
inc num_char
Not_New_Char_Flag:
cmp al, 0dh
jne Not_New_Line_Flag <-- Change this to je New_Line_Flag
inc num_char
Not_New_Line_Flag: <-- Change this to New_Line_Flag:
jmp L1;
End_Flag:
call Display_Char_Results <-- Change this to jmp Display_Char_Results
Option1 ENDP
In the Option1 procedure you are not really counting the characters! Follow the flow with p.e. AL=65 and you'll see that the num_char variable doesn't get incremented. Also don't CALL the display routine because you programmed that particular display routine to NOT return here. So JMP to it.
Display_char_results PROC
mov edx, OFFSET prompt3
call writestring
mov edx, OFFSET prompt4
call writestring
mov eax, 0 <-- This can savely be deleted
mov eax, num_char
call WriteDec
call crlf
call mainMenu <-- Change this to jmp mainMenu
Display_char_results ENDP
Every Display_..._results procedure should not CALL but rather JUMP to the mainMenu label. That way you have got a loop that is not rapidly filling the stack and thus avoiding stack overflow.
JUMPLABEL5:
cmp al, '6'
call option6
exit
mainMenu ENDP
In this code snippet you don't do anything with the outcome of the compare. You could do it like
JUMPLABEL5:
cmp al, '6'
jne BadChoice
call option6 <-- Remember to change this into a jump!
BadChoice:
exit
mainMenu ENDP