Please, does anybody know how to code string input in assembly language? I'm using int 21
to display and input characters.

- 25,628
- 5
- 56
- 89

- 149
- 2
- 4
- 12
2 Answers
You can use function 0Ah
to read buffered input. Given a string buffer in ds:dx
it reads a string of up to length 255. The buffer layout is:
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).
An example of a small COM file that reads a string and then echos it back to the 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
Note that it will overwrite the input line (and it thus might not look the program is doing anything!)
Alternatively you can use function 01h
and read the characters yourself in a loop. Something like this (note it will overflow later buffers if more than 255 characters are entered):
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

- 29,780
- 4
- 43
- 53
-
If you want a one-byte string containing just the '$' (terminator for the ah=09h function), yes, but then there won't be any place to store the characters you read. `times 255 db` is the same as db 0, 0, 0, 0, [snip 250 times 0,], 0, which ensures there is room to store the characters. If you are using a different assembler the syntax to reserve space might be different (and/or you can use dynamic memory allocation). – user786653 Jul 22 '11 at 12:21
A string is just a series of characters, so you can use your int 21 code inside of a loop to get a string, one character at a time. Create a label in the data segment to hold your string, and each time you read a character, copy it to that label (incrementing an offset each time so your characters get stored sequentially). Stop looping when a certain character is read (perhaps enter).
Doing all this manually is tedious (think about how backspace will work) but you can do it. Alternatively, you can link against stdio, stdlib, etc. and call library functions to do much of the work for you.

- 71
- 4
-
Thank you very much. But I don know, how to make it. I know it will be proc like `mov ah, 1h` – AlbatrosDocsCoder Jul 21 '11 at 18:46
-
I cannot edit that post. Thank you very much. But I don't know, how to make it all. I don't know how to insert more chars in label. So i will have `string db "$$$"` and what now? Can I `mov string, al ; pressed character to db`? If yes, than what to do next? I don't know ho to increment character position... Can you please place sample code here? – AlbatrosDocsCoder Jul 21 '11 at 18:52
-
Hopefully this is still relevant for you. You can keep the memory location in a register rather than by using the label. That way, you write to the memory address that's in the register instead of just writing to the label each time. Then as you modify the address register (incrementing it for each character) you'll be writing to new memory locations. – Quinn Aug 08 '11 at 17:46