Start by thinking through what we need to do. I often advocate writing the comments first (although I rarely actually do it). We're going to need to generate an ascii character to represent each group of four bits (a nibble... or nybble if you like). The groups of four bits will contain a number from 0 to 15. We're going to want to "convert" these to ascii characters '0' through 'F'. '0' to '9' is easy - just add '0' (48 decimal or 30h hex), same as a decimal conversion. 'A' through 'F' don't follow immediately after '9', we need to add an extra 7 (27h if you want 'a' through 'f'). We need to process these in the correct order. We could isolate the first (most significant) 4 bits and shift 'em down, then the next four... The "rol" instruction comes in handy here. We can rotate the top 4 bits into the lowest 4 bit positions, where they'll be easy to print. If we keep doing this, we'll get each group of four bits - in order - and get our original number back. Unfortunately, we have to isolate the four bits to "convert" and print them, and this will trash our number - we'll have to make a copy. If you're using a dos interrupt that prints dl, making a copy in dl may be convenient (but you'll probably still have to save ax). We isolate 4 bits, add '0', check to see if we have to add another 7, and print it. then we loop back and "rol" another four into position... until done.
; initialize counter
; looptop:
; rotate 4 into position
; save number
; isolate lowest 4 bits
; add '0'
; if it's over '9'
; add 7
; print it
; restore our number
; loop looptop
; return
Or as a real Linux program:
; nasm -f elf32 printhex.asm
; ld -o printhex printhex.o
global _start
section .text
_start:
nop
mov eax, 1234ABCDh
call printhex
mov al, 10 ; cosmetic linefeed
call putc
exit:
mov eax, 1
int 80h
printhex:
mov ecx, 8 ; 8 digits to print
.top:
rol eax, 4
push eax
and al, 0Fh
add al, '0'
cmp al, '9'
jbe .skip
add al, 7
.skip:
call putc
; or
; stosb
; for dos
; mov ah, 0Eh
; mov bx, 7
; int 10h
; or
; int 29h
pop eax
sub ecx, 1
jnz .top
; or
; loop .top
ret
putc:
push edx
push ecx
push ebx
push eax
mov ecx, esp
mov edx, 1
mov ebx, 1
mov eax, 4
int 80h
pop eax
pop ebx
pop ecx
pop edx
ret
;-------------------
If you're only doing bytes, there are easier ways, but it's the same general principle. A lookup table is also pretty simple.
hexdigits db '0123456789ABCDEF"
and use the isolated four bits as an index into that table, instead of the add '0', etc. Yeah, that's better - saves the conditional jump...
...
; save number
and eax, 0Fh
mov al, [hexdigits + eax]
; print (or stosb)
...
Something like that...
Best,
Frank