There are a number of issues with your code. Ross and I have pointed some out in the comments. You should read my General Bootloader Tips. Although not related to your actual problem you should set up DS (and ES if you eventually need it) to 0 because you use an origin point of 0x7c00 (org 0x7c00). You should also set up the stack somewhere you know your code won't be clobbering. I'd add this code to the top before:
    mov si, HelloString
    call print_string
Change it to be:
    xor ax, ax         ; AX=0
    mov ds, ax
    mov es, ax
    mov ss, ax         ; SS=ES=DS=0
    mov sp, 0x7c00     ; Place stack before the bootloader. Grows down from 0x0000:0x7c00
    mov si, HelloString
    call print_string
After your code is finished running you should place the CPU in an infinite loop so that it doesn't continue by executing your functions beneath the main code. So before the label read_name: place an infinite loop. Something like this is typical:
    cli                ; Turn off interrupts        
endloop:
    hlt                ; Halt processor until next interrupt encountered
    jmp endloop        ; Jump back just in case we get an MNI (non-maskable interrupt)
You have some bugs in your read_char function. One of the best places for BIOS Interrupt information is Ralph Brown's Interrupt List. Int 0x16/AH=0 is documented as:
AH = 00h
Return:
AH = BIOS scan code
AL = ASCII character
You should be using the ASCII character in AL to store into your string buffer. You should also be comparing AL with 0x0d, not AH (Which is the keyboard scan code, NOT the ASCII character). You also are storing data into your string buffer before you read the characters with int 0x16. You need to put them in the buffer after. When you reach stop_reading: you will want to place a NUL (0x00) character at the end of the buffer.
Your code for read_name could look like:
read_name:
read_char:
    mov ah, 0h  ; read character from keyboard
    int 0x16    ; store it in AL
    cmp al, 0x0d    ; check for enter
    je stop_reading
    mov [di], al    ; save it in the buffer
    inc di      ; next char
    mov ah, 0eh     ; display character in AL
    int 0x10    ; echo it
    jmp read_char   ; an so on
stop_reading:
    mov byte [di], 0x00    ; NUL terminate buffer
    mov si, EoL
    call print_string
    ret
The revised bootloader could look like:
[bits 16]
[org 0x7c00]
    xor ax, ax         ; AX=0
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x7c00     ; Place stack before the bootloader. Grows down from 0x0000:0x7c00
    mov si, HelloString
    call print_string
    mov di, name
    call read_name
    mov si, name
    call print_string
    cli                ; Turn off interrupts        
endloop:
    hlt                ; Halt processor until next interrupt encountered
    jmp endloop        ; Jump back just in case we get an MNI (non-maskable interrupt)
read_name:
read_char:
    mov ah, 0h         ; read character from keyboard
    int 0x16           ; store it in AL
    cmp al, 0x0d       ; check for enter
    je stop_reading
    mov [di], al       ; save it in the buffer
    inc di             ; next char
    mov ah, 0eh        ; display character in AL
    int 0x10           ; echo it
    jmp read_char      ; an so on
stop_reading:
    mov byte [di], 0   ; NUL terminate buffer
    mov si, EoL
    call print_string
    ret
print_char:
    mov ah, 0x0e       ; one char
    mov bh, 0x00       ; page number
    mov bl, 0x07       ; font color
    int 0x10
    ret
print_string:
next_char:
    mov al, [si]
    inc si
    or al, al
    jz exit_function
    call print_char
    jmp next_char
exit_function:
    ret
;data
HelloString db 'Enter your name', 0xd, 0xa, 0
name times 20 db 0
EoL db 0xd, 0xa, 0
times 510 - ($ - $$) db 0;
dw 0xaa55
I highly recommend using BOCHS to debug bootloaders. It has a built in debugger that understands real mode and real mode addressing and is better suited for debugging bootloaders than QEMU