Si ya está en Linux, no es necesario que haga la conversión usted mismo. Simplemente use printf en su lugar:
;
; 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
Tenga en cuenta que printf
usa la convención de llamada cdecl, por lo que necesitamos restaurar el puntero de la pila después, es decir, agregar 4 bytes por parámetro pasado a la función.
Tienes que convertirlo en una cadena; si estás hablando de números hexadecimales, es bastante fácil. Cualquier número se puede representar de esta manera:
0xa31f = 0xf * 16^0 + 0x1 * 16^1 + 3 * 16^2 + 0xa * 16^3
Entonces, cuando tenga este número, debe dividirlo como se muestra y luego convertir cada "sección" a su equivalente ASCII.
Obtener las cuatro partes se hace fácilmente con un poco de magia, en particular con un desplazamiento a la derecha para mover la parte que nos interesa en los primeros cuatro bits y luego Y el resultado con 0xf para aislarlo del resto. Esto es lo que quiero decir (supongamos que queremos tomar el 3):
0xa31f -> shift right by 8 = 0x00a3 -> AND with 0xf = 0x0003
Ahora que tenemos un solo número, tenemos que convertirlo a su valor ASCII. Si el número es menor o igual a 9, simplemente podemos agregar el valor ASCII de 0 (0x30), si es mayor que 9, debemos usar el valor ASCII de a (0x61).
Aquí está, ahora solo tenemos que 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
PD: Sé que este es un código de 16 bits pero sigo usando el antiguo TASM :P
PPS: esta es la sintaxis de Intel, sin embargo, la conversión a la sintaxis de AT&T no es difícil, mire aquí.