New to assembly.. this is the code. it reads sequence of characters and ends when you press enter
but the sequence of input characters has no limit when entered.. how to limit number of characters? for example i can only type 20 characters and the program will end?
and what does AL
in CMP
represent, and why 0DH
? i am confused in that line (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
The prg reads the chars one by one, storing it at Adress 1000 and following. it obviously doesnt care for the input's length, and stops as soon as 0x0d is read (which is a newline, so it reads until enter is pressed)
( I replaced "mov [di],al" + "inc di" with "stosb" which does exactly the same thing )
to add a "max length" check, you could do something like this inside the loop:
mov ax, DI
sub ax, 0x1000
cmp ax, <the max length you want to read>
jae END
Note: the enter is not saved, so if you change SI (that currently points to the last char entered), will have a problem determining the string's end. Better store the 0x0d too (or even better a 0x00), to have a end-of-string marker:
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
or storing a 0x00 and input's end:
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
One more idea on "limit the amount of chars read" (Instead of checking DI for 0x1000+20 to jump out of the read-loop) would be to use CX as counter and loop
(loop is a conditional jump that decreases CX and jumps if CX didn't reach 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