如何结束输入的字符序列:ASM: Int 21h function 01h

how to end the input sequence of characters: ASM: Int 21h function 01h

汇编新手..这是代码。它读取字符序列并在您按 enter

时结束

但是输入时输入字符的顺序没有限制..如何限制字符数?例如,我只能输入 20 个字符,程序就会结束?

CMP中的AL代表什么,为什么0DH?我对该行感到困惑 (CMP AL,0DH)

MAIN PROC

;INITIALIZE DS
MOV AX,@DATA     
MOV DS,AX

MOV     DI,1000H
MOV     AH,01H
LOOP:
INT     21H
CMP     AL,0DH
JE      END
MOV     [DI],AL
INC     DI
JMP     LOOP

END:
MOV AH,4CH         ;DOS EXIT FUNCTION
INT 21H            ;EXECUTE

MAIN ENDP
END MAIN

prg 逐个读取字符,存储在地址1000 及以下。它显然不关心输入的长度,并在读取 0x0d 后立即停止(这是一个换行符,因此它会读取直到按下 enter)

(我用 "stosb" 替换了 "mov [di],al" + "inc di",这完全一样)

要添加一个 "max length" 检查,你可以在循环中做这样的事情:

mov ax, DI
sub ax, 0x1000
cmp ax, <the max length you want to read>
jae END

注意:输入未保存,因此如果您更改 SI(当前指向输入的最后一个字符),将无法确定字符串的结尾。 最好也存储 0x0d(或者更好的是 0x00),以获得字符串结束标记:

MAIN PROC

;INITIALIZE DS
MOV AX,@DATA     
MOV DS,AX
cld                 ; tell "stosb" to forward

MOV     DI,1000H    ; address where to string will be copied to
MOV     AH,01H      ; int 21 function 1: read char with echo
LOOP:
   INT     21H         ; read a char from keyboard
   stosb               ; store char in string
   CMP     AL,0DH      ; stop if enter is pressed (after storing, so 0x0d will be stored too)
JNE     LOOP

END:
MOV AH,4CH         ;DOS EXIT FUNCTION
INT 21H            ;EXECUTE

MAIN ENDP

或存储 0x00 和输入的结尾:

MAIN PROC

;INITIALIZE DS
MOV AX,@DATA     
MOV DS,AX
cld                 ; tell "stosb" to forward

MOV     DI,1000H    ; address where to string will be copied to
MOV     AH,01H      ; int 21 function 1: read char with echo
LOOP:
   INT     21H         ; read a char from keyboard
   CMP     AL,0DH      ; stop if enter is pressed
   JE      END
   stosb               ; save al at DI and increase DI by one
JMP     LOOP

END:
mov [di], 0         ; terminate string (instead of 0x0d)
MOV AH,4CH         ;DOS EXIT FUNCTION
INT 21H            ;EXECUTE

MAIN ENDP

关于 "limit the amount of chars read" 的另一个想法(而不是检查 0x1000+20 的 DI 以跳出读取循环)将使用 CX 作为计数器和 loop(循环是有条件的减少 CX 的跳跃,如果 CX 未达到 0 则跳跃):

MAIN PROC

;INITIALIZE DS
MOV AX,@DATA     
MOV DS,AX
cld                 ; tell "stosb" to forward

mov     cx, 20      ; make sure to maximum read 20 chars
MOV     DI,1000H    ; address where to string will be copied to
MOV     AH,01H      ; int 21 function 1: read char with echo
LOOP:
   INT     21H         ; read a char from keyboard
   CMP     AL,0DH      ; stop if enter is pressed
   JE      END
   stosb               ; save al at DI and increase DI by one
loop     LOOP

END:
mov [di], 0         ; terminate string (instead of 0x0d)
MOV AH,4CH         ;DOS EXIT FUNCTION
INT 21H            ;EXECUTE

MAIN ENDP

我认为您正在使用 DOS 读取字符功能,因此只需将循环计数器计数到 20,或从 20 减到 0 作为循环退出条件。 cmp al, 0dH 比较你刚刚读到的字符是否是\r。 (DOS ah=1 / int 21 returns al 寄存器中的字符)。有关更多信息,请参阅 x86 标签 wiki。 – 彼得科德斯。

    10qu Peter Cordes. have done it here and works perfectly!