汇编语言程序陷入无限循环

时间:2015-04-23 04:56:15

标签: assembly masm irvine32

程序提示用户输入段落后,我的程序似乎停留在循环中。

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

1 个答案:

答案 0 :(得分:1)

您的计划主要存在流量问题。当我们使用call指令时,我们希望返回此处。但是你的代码只是尖叫到jmp,所以你应该用它来纠正问题。

cmp al, '1'
jne JUMPLABEL1
call Option1   <-- Change this to   jmp Option1

JUMPLABEL1:

每次你有一个像以前一样的代码块时,你不应该调用,而应该JUMP到相关的 Option _ 程序。

...
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 

Option1 程序中,您并没有真正计算角色!按照p.e.的流程。 AL = 65,您将看到 num_char 变量不会增加。也不要调用显示例程,因为您编写了特定的显示例程而不返回此处。所以JMP就可以了。

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

每个显示_...结果过程不应该调用,而应该是 mainMenu 标签的JUMP。这样你就得到了一个没有快速填充堆栈的循环,从而避免了堆栈溢出。

JUMPLABEL5:
cmp al, '6'
call option6
exit 
mainMenu ENDP

在此代码段中,您不会对比较的结果做任何事情。你可以这样做

JUMPLABEL5:
 cmp al, '6'
 jne BadChoice
 call option6       <-- Remember to change this into a jump!
BadChoice:
 exit 
mainMenu ENDP