Si vous êtes déjà sous Linux, il n'est pas nécessaire de faire la conversion vous-même. Utilisez simplement printf à la place :
;
; 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
Notez que printf
utilise la convention d'appel cdecl, nous devons donc restaurer le pointeur de pile par la suite, c'est-à-dire ajouter 4 octets par paramètre passé à la fonction.
Vous devez le convertir en chaîne ; si vous parlez de nombres hexadécimaux, c'est assez facile. N'importe quel nombre peut être représenté de cette manière :
0xa31f = 0xf * 16^0 + 0x1 * 16^1 + 3 * 16^2 + 0xa * 16^3
Ainsi, lorsque vous avez ce nombre, vous devez le diviser comme je l'ai montré, puis convertir chaque "section" en son équivalent ASCII.
Obtenir les quatre parties se fait facilement avec un peu de magie, notamment avec un décalage vers la droite pour déplacer la partie qui nous intéresse dans les quatre premiers bits puis ET le résultat avec 0xf pour l'isoler du reste. Voici ce que je veux dire (par opposition à nous voulons prendre le 3):
0xa31f -> shift right by 8 = 0x00a3 -> AND with 0xf = 0x0003
Maintenant que nous avons un seul nombre, nous devons le convertir en sa valeur ASCII. Si le nombre est inférieur ou égal à 9, nous pouvons simplement ajouter la valeur ASCII de 0 (0x30), s'il est supérieur à 9, nous devons utiliser la valeur ASCII de a (0x61).
Le voici, il ne nous reste plus qu'à le coder :
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 : Je sais que c'est du code 16 bits mais j'utilise toujours l'ancien TASM :P
SPP : c'est la syntaxe Intel, la conversion en syntaxe AT&T n'est cependant pas difficile, regardez ici.