Pokud již používáte Linux, není třeba provádět konverzi sami. Stačí místo toho použít 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
Všimněte si, že printf
používá konvenci volání cdecl, takže musíme poté obnovit ukazatel zásobníku, tj. přidat 4 bajty na parametr předaný funkci.
Musíte jej převést do řetězce; pokud mluvíte o hexadecimálních číslech, je to docela snadné. Libovolné číslo lze znázornit takto:
0xa31f = 0xf * 16^0 + 0x1 * 16^1 + 3 * 16^2 + 0xa * 16^3
Takže když máte toto číslo, musíte ho rozdělit, jak jsem ukázal, a poté převést každou "sekci" na její ekvivalent ASCII.
Získání čtyř částí se snadno provede trochou magie, zejména posunutím doprava, abyste přesunuli část, která nás zajímá, v prvních čtyřech bitech A výsledek s 0xf, abyste ji izolovali od zbytku. Zde je to, co mám na mysli (protože chceme vzít 3):
0xa31f -> shift right by 8 = 0x00a3 -> AND with 0xf = 0x0003
Nyní, když máme jediné číslo, musíme ho převést na jeho ASCII hodnotu. Pokud je číslo menší nebo rovno 9, můžeme přidat pouze ASCII hodnotu 0 (0x30), pokud je větší než 9, musíme použít ASCII hodnotu a (0x61).
Tady to je, teď to jen musíme nakódovat:
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: Vím, že se jedná o 16bitový kód, ale stále používám starý TASM :P
PPS: toto je syntaxe Intelu, převod na syntaxi AT&T však není obtížný, podívejte se sem.