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

时间:2016-06-09 09:01:11

标签: assembly tasm

汇编新手..这是代码。它会读取字符序列,并在您按Enter键时结束

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

AL中的CMP代表什么,以及为什么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

2 个答案:

答案 0 :(得分:3)

prg逐个读取字符,将其存储在Adress 1000及其后。它显然不关心输入的长度,并且一旦读取0x0d就停止(这是一个换行符,所以直到输入被按下才会读取)

(我替换了" mov [di],al" +" inc di"与" stosb"完全相同的事情)

添加"最大长度"检查,你可以在循环中做这样的事情:

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

另一个想法是&#34;限制读取的字符数&#34; (而不是检查DI为0x1000 + 20跳出读循环)将使用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

答案 1 :(得分:0)

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

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