Вы можете использовать функцию 0Ah
для чтения буферизованного ввода.Имея строковый буфер в ds:dx
, он читает строку длиной до 255. Макет буфера:
Byte 0 String length (0-255)
Byte 1 Bytes read (0-255, filled by DOS on return)
Bytes 2-..Length+2 (The character string including newline as read by DOS).
Пример небольшого COM-файла, который читает строку и затем выводит ее обратно вuser:
org 0x100
start:
push cs
pop ds ; COM file, ds = cs
mov ah, 0x0A ; Function 0Ah Buffered input
mov dx, string_buf ; ds:dx points to string buffer
int 0x21
movzx si, byte [string_buf+1] ; get number of chars read
mov dx, string_buf + 2 ; start of actual string
add si, dx ; si points to string + number of chars read
mov byte [si], '$' ; Terminate string
mov ah, 0x09 ; Function 09h Print character string
int 0x21 ; ds:dx points to string
; Exit
mov ax, 0x4c00
int 0x21
string_buf:
db 255 ; size of buffer in characters
db 0 ; filled by DOS with actual size
times 255 db 0 ; actual string
Обратите внимание, что он перезапишет строку ввода (и, следовательно, может не выглядеть, что программа что-то делает!)
В качестве альтернативы вы можете использовать function 01h
и читайте символы самостоятельно в цикле.Примерно так (обратите внимание, что более поздние буферы будут переполнены, если введено более 255 символов):
org 0x100
start:
push cs
pop ax
mov ds, ax
mov es, ax; make sure ds = es = cs
mov di, string ; es:di points to string
cld ; clear direction flag (so stosb incremements rather than decrements)
read_loop:
mov ah, 0x01 ; Function 01h Read character from stdin with echo
int 0x21
cmp al, 0x0D ; character is carriage return?
je read_done ; yes? exit the loop
stosb ; store the character at es:di and increment di
jmp read_loop ; loop again
read_done:
mov al, '$'
stosb ; 'Make sure the string is '$' terminated
mov dx, string ; ds:dx points to string
mov ah, 0x09 ; Function 09h Print character string
int 0x21
; Exit
mov ax, 0x4c00
int 0x21
string:
times 255 db 0 ; reserve room for 255 characters