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

TASM汇编宏打印异常:输入字符串后程序阻塞问题求助

Fixing Your TASM Program's Hang After Input

Let's break down why your assembly program is hanging when you press Enter, and fix the issues step by step.

1. Critical: Missing Input Buffer for INT 21H AH=0AH

The biggest problem here is how you're using the DOS buffered input function (AH=0AH). This function requires you to pass a pre-defined input buffer via the DX register—your code skips this entirely, so the system writes input data to a random memory location. This corrupts your program's data or code, leading to the hang.

Fix: Add an Input Buffer

First, add a properly structured input buffer to your DATA segment. The buffer needs three parts:

  • A byte defining the maximum number of characters to accept
  • A byte that DOS will fill with the actual number of characters entered (excluding the Enter key)
  • Space to store the input characters
DATA SEGMENT PARA PUBLIC 'DATA'
MSG1 DB 0DH, 0AH, 'PLEASE INPUT YOUR STRING', '$'
MSG2 DB 0DH, 0AH, 'THE SUM IS', '$'
NEWLINE DB 0DH, 0AH, '$'
; Add input buffer here
INPUT_BUFFER DB 255   ; Max characters we can accept (adjust as needed)
             DB ?     ; DOS will write actual input length here
             DB 255 DUP(0) ; Storage for input characters
TOTAL DB ?
DATA ENDS

Then, point DX to this buffer before calling INT 21H AH=0AH:

WRITE MSG1
WRITE NEWLINE
LEA DX, INPUT_BUFFER ; Set DX to point to our input buffer
MOV AH, 0AH
INT 21H ; Read input correctly now

2. Incorrect Loop Counter & String Pointer

Your current code uses MOV CL, BYTE PTR DS:[0001] to get the input length, which points to a random byte in your DATA segment (the second byte of MSG1, which is 0AH—a newline character). That's why your loop runs incorrectly, contributing to the hang.

Fix: Use the Input Buffer's Length Field

Update your loop setup to use the actual input length from the buffer, and start reading from the first input character:

MOV CL, INPUT_BUFFER+1 ; Get actual number of characters entered
MOV SI, OFFSET INPUT_BUFFER+2 ; Start at the first input character (skip buffer metadata)
MOV DX, 0 ; Initialize sum to 0
MOV BL, 2 ; For even/odd check

3. Minor Logic Cleanup (Optional)

Your SUM procedure works, but it's redundant to re-read the ASCII character and convert it again (you already did SUB AL, 30H in the main loop). You can simplify this by handling the addition directly in the main loop to avoid procedure call overhead:

L:
XOR AX, AX
MOV AL, BYTE PTR [SI]
CMP AL, 20H ; Check for space
JE SPACE
SUB AL, 30H ; Convert ASCII to digit
TEST AL, 1 ; Faster even/odd check than DIV BL
JNZ SPACE
ADD DL, AL ; Add even digit to sum directly
SPACE:
INC SI
LOOP L

4. Fix Sum Output (Current Code Prints Non-ASCII Values)

Right now, WRITE2 TOTAL outputs the numeric sum directly (e.g., if the sum is 10, TOTAL holds 0AH), which DOS interprets as a control character (newline) instead of the string "10".

Fix: Convert Numeric Sum to ASCII

Add a procedure to convert a byte-sized number to its readable ASCII string representation:

PRINT_NUM PROC
    ; Input: DL = numeric sum (0-255)
    ; Output: Prints the sum as ASCII characters
    PUSH AX
    PUSH BX
    PUSH CX
    MOV CX, 0
    MOV BX, 10
    ; Split number into individual digits
    NEXT_DIGIT:
        XOR AX, AX
        MOV AL, DL
        DIV BX
        ADD AH, 30H ; Convert remainder to ASCII
        PUSH AX
        INC CX
        MOV DL, AL
        CMP AL, 0
        JNE NEXT_DIGIT
    ; Print digits in reverse order
    PRINT_LOOP:
        POP AX
        MOV DL, AH
        MOV AH, 02H
        INT 21H
        LOOP PRINT_LOOP
    POP CX
    POP BX
    POP AX
    RET
PRINT_NUM ENDP

Then replace WRITE2 TOTAL with:

WRITE MSG2
MOV DL, TOTAL
CALL PRINT_NUM

Full Fixed Code

Here's the complete corrected code with all fixes applied:

DATA SEGMENT PARA PUBLIC 'DATA'
MSG1 DB 0DH, 0AH, 'PLEASE INPUT YOUR STRING', '$'
MSG2 DB 0DH, 0AH, 'THE SUM IS', '$'
NEWLINE DB 0DH, 0AH, '$'
INPUT_BUFFER DB 255
             DB ?
             DB 255 DUP(0)
TOTAL DB ?
DATA ENDS

WRITE MACRO MSG
MOV AH, 09H
LEA DX, MSG
INT 21H
ENDM

CODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE, DS:DATA

START PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX

WRITE MSG1
WRITE NEWLINE

LEA DX, INPUT_BUFFER
MOV AH,0AH
INT 21H ;READ INPUT

MOV CL, INPUT_BUFFER+1
MOV SI, OFFSET INPUT_BUFFER+2
MOV DX,0
MOV BL,2

L:
XOR AX, AX
MOV AL, BYTE PTR [SI]
CMP AL, 20H
JE SPACE
SUB AL,30H
TEST AL,1
JNZ SPACE
ADD DL,AL
SPACE:
INC SI
LOOP L

MOV TOTAL,DL
WRITE MSG2
MOV DL, TOTAL
CALL PRINT_NUM

MOV AH,4CH
INT 21H
RET
START ENDP

PRINT_NUM PROC
PUSH AX
PUSH BX
PUSH CX
MOV CX,0
MOV BX,10
NEXT_DIGIT:
XOR AX,AX
MOV AL,DL
DIV BX
ADD AH,30H
PUSH AX
INC CX
MOV DL,AL
CMP AL,0
JNE NEXT_DIGIT
PRINT_LOOP:
POP AX
MOV DL,AH
MOV AH,02H
INT 21H
LOOP PRINT_LOOP
POP CX
POP BX
POP AX
RET
PRINT_NUM ENDP

CODE ENDS
END START

This should resolve the hang and correctly calculate and display the sum of even digits in your input string.

内容的提问来源于stack exchange,提问作者Andrei Brașoveanu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:57:35