It has been a while since I've done DOS, and my memory isn't what it was. I think your input buffer is too small. First byte is "maximum" - as I recall, it needs to include the CR which will end input. Try it with 2, but I think you're going to want 3. Second byte will be filled in with the number of bytes actually entered. 0 is good there. Then you want at least 2 - I think 3 - zeros before your '$' to hold the input text (and the CR). When you want to display it, the input text will start at "buf + 2". I think "mov dx, buf" is going to give you a couple of "garbage" characters before your entered text - won't do any great harm.
As a general rule, when you ask for help with code, we need to know what you "expect" to happen (fairly obvious in this case, I think) and what actually happened. I'm guessing that you'll overwrite the "$" which is expected to end output, and will probably see a bunch of "garbage" starting with the first digit you entered.
bits 16
org 0x100;
jmp main ;
buf: db 3,0, 0, 0, 0, '$'
cr_lf:
db 13,10,'$' ; carriage return and line feed
main:
mov ah,0ah ; accept string from user
mov dx,buf ; address for string
int 21h ;
mov ah,09 ; display string
mov dx,cr_lf ; display carriage return and line feed
int 21h ;
mov ah,09 ; display string
mov dx,buf + 2 ; display string starting from address of buf (+ 2!)
int 21h ;
int 20h ;
Untested(!), but I think that'll do better. If not, let us know what did happen.
To "do anything" with this number (besides display it) you'll need to convert from text to number, but you probably know that...
Best,
Frank