I am only a beginner in assembly and was reading the OS book by Nick Blundell, when I came across the question of writing a function which could print hexadecimal number. But, despite verifying the logic multiple times , I can't seem to find why this code doesn't work. Please help, I would be grateful.
HEX_OUT:    db  '0x0000', 0
MASK:       dw  0b1111000000000000
COUNTER:    db  3
print_string :
    pusha                               ;SAVES ALL REGISTER VALUES TO BE RESTORED WHEN RETURNING.
    mov ah, 0x0e
    jmp print_loop                      ;NOT COMPULSORY
    print_loop :
        mov al, [bx]
        add bx, 1                       ;ADD 1, NOT 8, NOT 16.
        int 0x10
        cmp al, 0                       ;SETS A FLAG ACCORDING TO RESULT OF COMPARISON.
        jne print_loop                  ;CAUSES LOOP.
        jmp final_block                 ;CAN BE REPLACED BY THE STATEMENTS IN final_block, NO NEED FOR MAKING NEW LABEL.
    final_block :
        popa
        ret                             ;RETURNS TO THE POINT WHERE CALL HAPPENED.
print_hex :
    pusha
    mov bx, HEX_OUT
    add bx, 2
    alter_loop :                        ;LOOP TO ALTER HEX_OUT
        mov ax, [MASK]
        cmp ax, 0                       ;CONDITION TO END LOOP
        je after_loop
        mov ax, dx                      ;GETTING(INTO AX) THE DATA FOR N-TH POSITION 
        and ax, [MASK]
        mov cx, [COUNTER]
        shift_loop :
            cmp cx, 0
            je end_shift_loop
            shr ax, 4
            sub cx, 1
        end_shift_loop:
        cmp ax, 0x0009                       ;DO HEX->ALPHABET IF NUMBER IS GREATER THAN 9
        jle skip_hex_to_alphabet
        add ax, 39                       ;EQUIVALENT TO (sub ax, 48--- sub ax, 9 ---add ax, 96)
        skip_hex_to_alphabet :
        add ax, 48                      ;ADDING 48(ASCII OF 0), IS ALREADY SUBTRACTED IF N-TH NUMBER>9
        mov [bx], al                    ;STORING DATA IN LOCATION POINTED TO BY BX
        add bx, 1                       ;INCREMENT FOR LOOP
        mov ax, [MASK]                  ;CHANGING MASK
        shr ax, 4
        mov [MASK], ax
        mov ax, [COUNTER]               ;UPDATING COUNTER
        sub ax, 1
        mov [COUNTER], ax
        jmp alter_loop
    after_loop :
    mov bx, HEX_OUT
    call print_string    
    popa
    ret  
Upon calling the function like :-
mov dx, 0x1fd6
call print_hex
It prints, 0xWGd0 instead of 0x1fd6 .
 
    