You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LC3汇编程序循环无法终止问题排查求助

Troubleshooting Your LC-3 Endless Loop & String/Word Count Issues

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_ELEMENTS with BR COUNT_ELEMENTS to 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 LDR Usage: Removed the invalid LDR calls for counters—we use the counter values directly and add 48 to convert them to ASCII digits.

内容的提问来源于stack exchange,提问作者JackSlayer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:37:47