x86 Assembly String Buffer Number to ASCII
<p>I was writing an x86 assembly program to output a number in hexadecimal. The program was assembled using nasm and the image file ran by qemu. The behavior of the program confused me a lot. As the working program below suggests, I wouldn't have to add 0x30 to a digit to get it to print the character of that digit.</p>

<pre><code>    ; Boot sector code offset: 0x7c00
[org 0x7c00]

    mov dx, 0x1fb6 ; The hexadecimal to be printed
    call print_hex ; call the function
    jmp $ ; jump infinitely

%include "print_string.asm" ; Include the print_string function

print_hex:
    pusha ; push all registers to stack
    mov ax, 0x4 ; rotate through the number four times
print_hex_loop:
    cmp ax, 0x0 ; compare the counter with 0
    jle print_hex_end ; if it is zero then jump to the end  
    mov cx, dx ; move dx to cx
    and cx, 0x000F ; take the lower four binary digits of cx
    cmp cx, 0xa ;compare the digits with 0xa
    jge print_hex_letter ; if it is larger than a, jump to printing character
    add cx, 0x0 ; otherwise print the ascii of a number
    jmp print_hex_modify_string ; jump to routine for modifing the template
print_hex_letter:
    add cx, 0x7 ; print the ascii of a letter
print_hex_modify_string:
    mov bx, HEX_OUT ; bring the address of HEX_OUT into dx
    add bx, 0x1 ; skip the 0x
    add bx, ax ; add the bias
    add byte [bx], cl ; move the character into its position
    shr dx, 4 ; shift right 4 bits
    sub ax, 0x1 ; subtract 1 from the counter
    jmp print_hex_loop ; jump back to the start of the function
print_hex_end:
    mov bx, HEX_OUT ; move the address of HEX_OUT to bx
    call print_string ; call the function print_string
    popa ; pop all registers from stack
    ret ; return to calling function

HEX_OUT:
    db '0x0000',0 ; The template string for printing

    times 510-($-$$) db 0 ; fill zeros
    dw 0xaa55 ; MAGIC_FLAG for boot
</code></pre>

<p>boot_sect.asm</p>

<pre><code>print_string:
    pusha
    mov ah, 0x0e
    mov al, [bx]
print_string_loop:
    cmp al, 0x0
    je print_string_end
    int 0x10
    add bx, 0x1
    mov al, [bx]
    jmp print_string_loop
print_string_end:
    popa
    ret
</code></pre>

<p>print_string.asm</p>

<p>The output of this program is what I expected, but when I tried to add 0x30 on the numerals to get the ASCII code of the digits, the output was gibberish. Is there some trick to it or am I missing some key points here?</p>

<p>Thanks!</p>