LC3汇编程序循环无法终止问题排查求助
Hey there! Let's dig into why your LC-3 program is stuck in an endless loop and fix those issues step by step. Since you're only 12 hours into assembly, it's totally normal to hit these snags—let's break it down.
Key Issues Causing the Loop & Functionality Problems
1. Input Loop Termination Doesn't Match Requirements
Your current input loop (GET_USER_INPUT) only stops when the user presses Enter (BRz COUNT_LENGTH after subtracting 10 from R0). But the task specifies the input should end with a period and max out at 80 characters. This mismatch means the loop will never stop when the user enters a period, and could even write past your 80-byte SENTENCE buffer if the user types too much.
2. Recursive Loop in COUNT_ELEMENTS Causes Stack Overflow
You're using JSR COUNT_ELEMENTS to loop back, which pushes a return address to the stack every time. Since there's no exit condition that pops this address, the stack will overflow, and the program will get stuck in an infinite recursive loop. We need to use a simple branch instruction instead of a subroutine call here.
3. Invalid LDR Instructions in Output Section
Lines like LDR R3, R3, #0 and LDR R1, R1, #0 are incorrect. LDR expects a memory address as the base register, but R3 and R1 are just counter values. You don't need to load them from memory—they already hold the counts directly.
4. Word Count Logic Flaws
- You initialize R3 to 1 immediately, which will count a word even if the input starts with spaces.
- You're incrementing the word count every time you hit a space, which will overcount if there are multiple consecutive spaces.
- You're counting the period as a character (since you check for the period after incrementing R1).
Fixed Code with Explanations
Here's the revised code with fixes for all the above issues:
.ORIG X3000 LEA R0, PROMPT_ENTER ; Display input prompt PUTS LEA R2, SENTENCE ; Point R2 to start of input buffer AND R3, R3, #0 ; Initialize word counter to 0 AND R1, R1, #0 ; Initialize character counter to 0 AND R5, R5, #0 ; Initialize space flag (0 = no recent space, 1 = recent space) ;---------USER INPUT LOOP (stops at period or 80 chars)------ GET_USER_INPUT: GETC OUT STR R0, R2, #0 ; Store character in buffer ; Check if we've reached 80 characters ADD R6, R1, #1 ; R6 = current char count + 1 ADD R6, R6, #-80 BRz COUNT_LENGTH ; If 80 chars, exit input loop ; Check if input is period (ASCII 46) ADD R0, R0, #-46 BRz COUNT_LENGTH ; If period, exit input loop ADD R0, R0, #46 ; Restore R0 value ; Otherwise, increment counters and buffer pointer ADD R2, R2, #1 ADD R1, R1, #1 BR GET_USER_INPUT ;--------COUNT WORDS & VALIDATE INPUT---- COUNT_LENGTH: ; Check if input is empty (only period or no chars) LEA R4, SENTENCE LDR R0, R4, #0 ADD R0, R0, #-46 BRz EMPTY ; Reset R4 to start of buffer, reset space flag LEA R4, SENTENCE AND R5, R5, #0 COUNT_ELEMENTS: LDR R0, R4, #0 ADD R0, R0, #-46 BRz END_OF_SENTENCE ; Exit loop when we hit the period ; Check if current character is space (ASCII 32) LDR R0, R4, #0 ADD R0, R0, #-32 BRz HANDLE_SPACE ; Not a space: if previous was space, increment word count ADD R5, R5, #0 BRnz SKIP_WORD_INC ADD R3, R3, #1 AND R5, R5, #0 ; Reset space flag SKIP_WORD_INC: ADD R4, R4, #1 BR COUNT_ELEMENTS HANDLE_SPACE: ADD R5, R5, #1 ; Set space flag to indicate recent space ADD R4, R4, #1 BR COUNT_ELEMENTS EMPTY: LEA R0, PROMPT_NULL PUTS HALT END_OF_SENTENCE: ; Add 1 to word count for the final word (since we stop at period) ADD R3, R3, #1 ; Output word count (convert to ASCII) AND R0, R0, #0 ADD R0, R3, #48 LEA R6, WORD_COUNT_MSG PUTS OUT LD R0, NEWLINE OUT ; Output character count (subtract 1 to exclude the period) AND R0, R0, #0 ADD R1, R1, #-1 ; Remove period from char count ADD R0, R1, #48 LEA R6, CHAR_COUNT_MSG PUTS OUT LD R0, NEWLINE OUT HALT ; Data section SENTENCE .BLKW #80 ; 80-byte input buffer NEWLINE .fill #10 ; ASCII newline WORD_COUNT_MSG .stringz "Word count: " CHAR_COUNT_MSG .stringz "Character count: " ;----MESSAGES------ PROMPT_ENTER .stringz "Enter a sentence (max 80 characters, ends with .): \n" PROMPT_NULL .stringz "Error: Please enter a non-empty sentence!\n" .END
Key Fixes Explained:
- Input Loop: Now stops when the user enters a period or hits 80 characters, matching your task requirements.
- Loop Control: Replaced
JSR COUNT_ELEMENTSwithBR COUNT_ELEMENTSto avoid recursive stack overflow. - Word Count: Added a space flag to only increment the word count when we transition from a space to a non-space character, fixing overcounts from multiple spaces. Also starts the word counter at 0 and adds 1 at the end for the final word.
- Character Count: Subtracts 1 from R1 to exclude the period from the total count.
- Valid
LDRUsage: Removed the invalidLDRcalls for counters—we use the counter values directly and add 48 to convert them to ASCII digits.
内容的提问来源于stack exchange,提问作者JackSlayer

