如何结束输入的字符序列: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!
汇编新手..这是代码。它读取字符序列并在您按 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!