X86 Assembly Help_value265

Hi,
I'm transitioning to assembly, starting with processor 8086.
The attached code is Masm 5 compatible and is a step up from Hello World, which linked and ran okay.
An endless loop exists, giving credence to this note.
Any comments or suggestions to resolve it would be appreciated, thanks!

.model small
.stack 100h
.data

name_prompt         db 'Enter your first name: $'
user_input          db 11, 0 ; Buffer for user's name (up to 10 characters + 1 null terminator)
range_prompt        db 'Enter the range of numbers (e.g., 0 to 10): $'
range_input         db 5, 0 ; Buffer for user's range input (up to 4 characters + 1 null terminator)
lower_bound         dw 0 ; Lower bound of the range
upper_bound         dw 0 ; Upper bound of the range
operand1            dw 0 ; First operand for flash card
operand2            dw 0 ; Second operand for flash card
correct_answer      dw 0 ; Correct answer for flash card
user_answer         db 0 ; User's answer for flash card
correct_count       db 0 ; Counter for correct answers
flash_card_prompt   db 'Flash Card: $'
correct_msg         db 'Correct!', 0Dh, 0Ah, '$'
incorrect_msg       db 'Incorrect!', 0Dh, 0Ah, '$'
result_prompt       db 'Number of Correct Answers: $'
hello_msg           db 'Hello World',0Dh, 0Ah, '$'
debug_msg           db 'Debug: ', 0
debug_end_msg       db 'Debug: End of Execution', 0

.code

 print_number proc
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
        ; Display a number
        mov bx, 10 ; Set divisor to 10

        print_digit:
            xor dx, dx ; Clear any previous remainder
            div bx ; Divide AX by 10, result in AX, remainder in DX
            push dx ; Push the remainder onto the stack
            inc dl ; Convert the remainder to ASCII
            add dl, '0'
            mov ah, 02h ; DOS print character function
            int 21h ; Call DOS interrupt

            pop dx ; Pop the remainder from the stack
            cmp ax, 0 ; Check if quotient is zero
            jnz print_digit ; If not, continue the loop
            ret
    print_number endp

    generate_random_number proc
        ; Seed the random number generator
        mov ah, 2Ch ; DOS get system time function
        int 21h ; Call DOS interrupt
        xor ah, ah ; Clear AH
        mov cx, dx ; Use CX as the seed for the random number generator

        ; Generate a random number in the range [lower_bound, upper_bound]
        mov ax, cx ; Use AX to store the random number
        sub ax, [lower_bound]
        inc ax

        ; Move the upper_bound value into a register (BX)
        mov bx, [upper_bound]
        xor dx, dx
        div bx ; Divide AX by BX, result in AX, remainder in DX
        add ax, [lower_bound]
        ret
    generate_random_number endp

    clear_keyboard_buffer proc
        ; Clear the keyboard buffer
        mov ah, 0Ch ; DOS flush keyboard buffer function
        int 21h ; Call DOS interrupt
        ret
    clear_keyboard_buffer endp

main proc
    mov ax, @data
    mov ds, ax
    mov es, ax
    mov ss, ax

    ; Display prompt for user's name
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
    mov ah, 09h         ; DOS print string function
    mov dx, offset name_prompt ; Offset of the message
    int 21h             ; Call DOS interrupt

    ; Read user's first name
    mov ah, 0Ah         ; DOS buffered input function
    lea dx, user_input  ; DX points to the buffer for input
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
    int 21h             ; Call DOS interrupt

    ; Clear the keyboard buffer
    call clear_keyboard_buffer

    ; Display prompt for the range of numbers
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
    mov ah, 09h         ; DOS print string function
    mov dx, offset range_prompt ; Offset of the message
    int 21h             ; Call DOS interrupt

    ; Read lower bound of the range
    mov ah, 0Ah         ; DOS buffered input function
    lea dx, range_input ; DX points to the buffer for input
    int 21h             ; Call DOS interrupt

    ; Convert ASCII input to integer (lower bound)
    mov al, [range_input + 2] ; ASCII character
    sub al, '0'               ; Convert ASCII to integer
    mov bl, 10                ; Multiplier for tens place
    mul bl                    ; Multiply AL by BL, result in AX
    mov [lower_bound], ax     ; Store the result

    ; Debug print for lower bound
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
    mov ah, 09h ; DOS print string function
    mov dx, offset range_prompt ; Prompt for debug print
    int 21h ; Call DOS interrupt

    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
    mov ax, [lower_bound] ; Load lower_bound into AX
    call print_number ; Display the lower bound
    mov ah, 09h ; DOS print string function
    mov dx, offset debug_msg ; Debug message
    int 21h ; Call DOS interrupt

    ; Read upper bound of the range
    mov ah, 0Ah         ; DOS buffered input function
    lea dx, range_input ; DX points to the buffer for input
    int 21h             ; Call DOS interrupt

    ; Convert ASCII input to integer (upper bound)
    mov al, [range_input + 3] ; ASCII character for tens place
    sub al, '0'
    mov bl, 10
    mul bl                    ; Multiply AL by BL, result in AX
    mov bh, 0                 ; Clear BH
    mov bl, [range_input + 2] ; ASCII character for units place
    sub bl, '0'               ; Convert ASCII to integer
    add ax, bx                ; Add to result (upper bound)
    mov [upper_bound], ax     ; Store the result

    ; Debug print for upper bound
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
    mov ah, 09h ; DOS print string function
    mov dx, offset range_prompt ; Prompt for debug print
    int 21h ; Call DOS interrupt

    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
    mov ax, [upper_bound] ; Load upper_bound into AX
    call print_number ; Display the upper bound
    mov ah, 09h ; DOS print string function
    mov dx, offset debug_msg ; Debug message
    int 21h ; Call DOS interrupt

    ; Preserve dx before calling generate_random_number
    push dx

    ; Generate random numbers in the specified range
    call generate_random_number   ; Call the generate_random_number procedure
    mov [operand1], ax

    call generate_random_number   ; Call the generate_random_number procedure
    mov [operand2], ax

    ; Restore dx after generate_random_number
    pop dx

    ; Generate and display flash cards
    mov cx, 10 ; Number of flash cards

    flash_cards_loop:
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
        ; Add debug print to check loop iteration
        mov ah, 09h ; DOS print string function
        mov dx, offset debug_msg
        int 21h ; Call DOS interrupt

        mov ax, cx
        call print_number ; Display loop iteration number

        ; Generate random numbers in the specified range
        call generate_random_number   ; Call the generate_random_number procedure
        mov [operand1], ax

        call generate_random_number   ; Call the generate_random_number procedure
        mov [operand2], ax

        ; Display flash card
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
        mov ah, 09h ; DOS print string function
        mov dx, offset flash_card_prompt
        int 21h ; Call DOS interrupt

        ; Display the first operand
        mov ax, [operand1]
        call print_number ; Display the operand

        ; Display operator (+ or -)
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
        mov ah, 02h ; DOS print character function
        mov dl, '+'
        int 21h ; Call DOS interrupt

        ; Display the second operand
        mov ax, [operand2]
        call print_number ; Display the operand

        ; Display equals sign
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
        mov ah, 02h ; DOS print character function
        mov dl, '='
        int 21h ; Call DOS interrupt

        ; Display the second operand
        mov ax, [operand2]
        call print_number;Display operand A2102 SYMBOL NOT DEFINED

        ; Display equals sign
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
        mov ah, 02h ; DOS print character function
        mov dl, '='
        int 21h ; Call DOS interrupt

        ; Read user's answer
        mov ah, 01h      ; DOS input character function
        int 21h          ; Call DOS interrupt
        sub al, '0'      ; Convert ASCII to integer
        mov bh, 0        ; Clear BH
        mov bX, [correct_answer];Load correct_answer into BL A2048 OP.MUST BE SAME SIZE

        ; Calculate the correct answer
        add bl, bh ; Clear high bits of BL
        cmp al, bl ; Compare AL with BL
        je  correct_answer_handler ; Jump if equal

        ; Display incorrect message
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
        mov ah, 09h ; DOS print string function
        mov dx, offset incorrect_msg
        int 21h ; Call DOS interrupt
        jmp next_flash_card ; Jump to the next flash card

    correct_answer_handler:
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
        ; Add debug print to check correct answer handling
        mov ah, 09h ; DOS print string function
        mov dx, offset debug_msg
        int 21h ; Call DOS interrupt

        mov dx, [correct_answer]
        call print_number ; Display correct answer

        ; Display correct message
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
        mov ah, 09h ; DOS print string function
        mov dx, offset correct_msg
        int 21h ; Call DOS interrupt

        ; Increment correct answer count
        mov al, [correct_count] ; Load the byte value into AL
        inc al                  ; Increment AL
        mov [correct_count], al ; Store the result back in memory
    next_flash_card:
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
        ; Add debug print to check loop termination
        mov ah, 09h ; DOS print string function
        mov dx, offset debug_msg
        int 21h ; Call DOS interrupt
        ; Move to the next flash card
        dec cx ; Decrement the loop counter
        jnz flash_cards_loop ; Jump if not zero
    ; Display the number of correct answers
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
    mov ah, 09h ; DOS print string function
    mov dx, offset result_prompt
    int 21h ; Call DOS interrupt
    ; Display the number of correct answers
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
    mov ah, 02h ; DOS print character function
    mov dl, [correct_count]
    add dl, '0'
    int 21h ; Call DOS interrupt
    ; Exit program
    mov ah, 4Ch ; DOS exit function
    int 21h ; Call DOS interrupt
main endp
END main
.text
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
    mov ah, 09h ; DOS print string function
    mov dx, offset hello_msg
    int 21h ; Call DOS interrupt
    mov ah, 09h ; DOS print string function
    ; Set DS to point to the data segment
    mov ax, @data
    mov ds, ax
    mov dx, offset debug_end_msg ; Debug message
    int 21h ; Call DOS interrupt
    mov ah, 4Ch ; DOS exit function
    int 21h ; Call DOS interrupt