Search code examples
assemblyx86hexasciireal-mode

How to convert normal bytes to ascii in assembly?


I am trying to write a function for my real mode operating system that will dump memory. I want the byte 0x0a to show up as '0A', 0xf3 to show up as 'F3' and so on and so forth. The code I wrote uses a table that consists of '0123456789ABCDEF', and uses the individual nibble as an offset to find the right character. First it saves the value, which is in al. Next it shifts al right by 4, removing the lower nibble and moving the higher nibble down. It then load the table into di, and zeros out ah. Next, it adds ax to di to find the offset. It then moves the value at di into al, and prints it. It then follows the same steps except that it then uses the low nibble instead of the high nibble. However, when I run it, it only prints out '33' repeatedly, instead of the actual hex numbers. Here is my code:

memdump:            
mov si, 0x7000      ;load si
loop:               
    mov al, [si]        ;put the value at si into al
    call printhex       ;call the hex printer
    inc si          ;increment si
    cmp si, 0x7CFF      ;are we done?
    je done         ;yes, return
    jmp loop        ;loop
printhex:           
    mov al, bl      ;save al
    shr al, 4       ;remove the lower nibble and move the higher nibble down
    mov di,hexbuffer    ;put the hexadecimal buffer in di
    xor ah, ah      ;remove everything from ah
    add di, ax      ;add the address to the buffer
    mov al, [di]        ;move the ascii char into al
    mov ah, 0x0E        ;teletype printing for int 0x10
    int 0x10        ;print the character
    mov bl, al      ;reload al
    shl al, 4       ;remove the high nibble
    shr al, 4       ;move the new high nibble down
    mov di, hexbuffer   ;reload the buffer
    xor ah, ah      ;zero out ah
    add di, ax      ;add the offset
    mov al, [di]        ;transfer the ascii char
    mov ah, 0x0E        ;teletype printing for int 0x10
    int 0x10        ;print the char
    mov al, ' '     ;now print a space
    int 0x10        ;print the space
    ret         ;return
done:               
    ret         ;return to kernel
    hexbuffer db '0123456789ABCDEF'

What is the problem with it? Thank you in advance.


Solution

  • One problem is that the mov al, bl; save al and the mov bl, al ; reload al have the operands reversed.

    If you are already writing your so-called operating system, you should be familiar with a debugger so you can fix your own mistakes.