EDIT: After Ped7g's comment, I reworked the code. This new one doesn't use the stack to reverse the string and the string is not read as a whole string, but it is read char by char until "Enter" is pressed. Below is the new code.
assume cs:code, ds:data
data segment
    message db 0Dh, 0Ah, "String: $"
    reverse db 0Dh, 0Ah, "Result: $"
    string db 255 dup(0)
    result db 255 dup('$')
data ends
code segment
start:
    mov ax, data
    mov ds, ax
    ; Print "String: "
    mov ah, 09h
    lea dx, message
    int 21h
    ; Set SI where we read the string
    lea si, string
    read:
        ; Read a single character from the keyboard
        mov ah, 01h
        int 21h
        ; Save it in the memory
        mov [si], al
        inc si
        ; Check if Enter is pressed (if not, then repeat reading)
        cmp al, 0Dh
        jnz read
    ; Calculate the length of the string read
    mov ax, si
    lea bx, string
    sub ax, bx
    ; Set DI at the last char of result
    lea di, result
    add di, ax
    ; Decrement one byte to position DI on the last char
    ; of the string (the Carriage Return)
    dec di
    ; Decrement one byte because we don't want to consider
    ; the Carriage Return as a part of our reversed string
    dec di
    ; Set SI at the first char of string
    lea si, string
    reverse_string:
        ; Copy from the beginning of the initial string
        ; to the end of the reversed string
        mov al, [si]
        mov [di], al
        ; Step
        inc si
        dec di
        ; Verify if we have reached the end of the initial string
        ; (if the "current" char is Carriage Return)
        cmp byte ptr [si], 0Dh
        jnz reverse_string
    ; Print "Result: "
    mov ah, 09h
    lea dx, reverse
    int 21h 
    write:
        ; Write the whole reversed string on standard output
        mov ah, 09h
        lea dx, result
        int 21h
    mov ah, 4Ch
    int 21h
code ends
end start
Old answer:
You can try to use the LIFO property of stack. Below is an example of code that reverses a string using it. The algorithm puts every character from the beginning of the input string, and then pops out to the result (in the reverse order).
assume cs:code, ds:data
data segment
    msg db 0Dh, 0Ah, "String: $"
    rev db 0Dh, 0Ah, "Result: $"
    buffer label byte
    str_maxlen db 255
    str_length db 0
    str_string db 255 dup(0)
    result db 255 dup('$')
data ends
code segment
start:
    mov ax,data
    mov ds,ax
    mov ah, 09h
    lea dx, msg
    int 21h         ; print "Your string"
    mov ah, 0Ah
    lea dx, buffer
    int 21h         ; read your string
    cmp str_length, 0
    je skip         ; check if the input is null
    mov ch, 0
    mov cl, str_length
    lea si, str_string
    put_on_stack:
        push [si]   ; copy on the stack (from string)
        inc si
        loop put_on_stack
    mov ch, 0
    mov cl, str_length
    lea di, result
    get_from_stack:
        pop [di]    ; copy back to memory (in result)
        inc di
        loop get_from_stack
    mov byte ptr [di], '$'
    skip:
    mov ah, 09h
    lea dx, rev
    int 21h         ; print "Result: "
    mov ah, 09h
    lea dx, result
    int 21h         ; print the result
    mov ah,4Ch
    int 21h
code ends
end start