Se sei già su Linux, non è necessario eseguire la conversione da solo. Usa invece printf:
;
; assemble and link with:
; nasm -f elf printf-test.asm && gcc -m32 -o printf-test printf-test.o
;
section .text
global main
extern printf
main:
mov eax, 0xDEADBEEF
push eax
push message
call printf
add esp, 8
ret
message db "Register = %08X", 10, 0
Nota che printf
usa la convenzione di chiamata cdecl quindi dobbiamo ripristinare il puntatore dello stack in seguito, ovvero aggiungere 4 byte per parametro passato alla funzione.
Devi convertirlo in una stringa; se stai parlando di numeri esadecimali è abbastanza facile. Qualsiasi numero può essere rappresentato in questo modo:
0xa31f = 0xf * 16^0 + 0x1 * 16^1 + 3 * 16^2 + 0xa * 16^3
Quindi, quando hai questo numero devi dividerlo come ho mostrato, quindi convertire ogni "sezione" nel suo equivalente ASCII.
Ottenere le quattro parti è facile con un po' di magia, in particolare con uno spostamento a destra per spostare la parte che ci interessa nei primi quattro bit, quindi E il risultato con 0xf per isolarlo dal resto. Ecco cosa intendo (supponiamo di voler prendere il 3):
0xa31f -> shift right by 8 = 0x00a3 -> AND with 0xf = 0x0003
Ora che abbiamo un singolo numero dobbiamo convertirlo nel suo valore ASCII. Se il numero è minore o uguale a 9 possiamo semplicemente aggiungere il valore ASCII di 0 (0x30), se è maggiore di 9 dobbiamo usare il valore ASCII di a (0x61).
Eccolo, ora dobbiamo solo codificarlo:
mov si, ??? ; si points to the target buffer
mov ax, 0a31fh ; ax contains the number we want to convert
mov bx, ax ; store a copy in bx
xor dx, dx ; dx will contain the result
mov cx, 3 ; cx's our counter
convert_loop:
mov ax, bx ; load the number into ax
and ax, 0fh ; we want the first 4 bits
cmp ax, 9h ; check what we should add
ja greater_than_9
add ax, 30h ; 0x30 ('0')
jmp converted
greater_than_9:
add ax, 61h ; or 0x61 ('a')
converted:
xchg al, ah ; put a null terminator after it
mov [si], ax ; (will be overwritten unless this
inc si ; is the last one)
shr bx, 4 ; get the next part
dec cx ; one less to do
jnz convert_loop
sub di, 4 ; di still points to the target buffer
PS: So che questo è un codice a 16 bit ma uso ancora il vecchio TASM :P
PPS: questa è la sintassi Intel, tuttavia la conversione nella sintassi AT&T non è difficile, guarda qui.