Wenn Sie bereits Linux verwenden, müssen Sie die Konvertierung nicht selbst durchführen. Verwenden Sie stattdessen einfach 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
Beachten Sie, dass printf
verwendet die cdecl-Aufrufkonvention, also müssen wir den Stapelzeiger danach wiederherstellen, d. h. 4 Bytes pro Parameter hinzufügen, der an die Funktion übergeben wird.
Sie müssen es in einen String umwandeln; Wenn Sie über Hex-Zahlen sprechen, ist es ziemlich einfach. Jede Zahl kann auf diese Weise dargestellt werden:
0xa31f = 0xf * 16^0 + 0x1 * 16^1 + 3 * 16^2 + 0xa * 16^3
Wenn Sie also diese Nummer haben, müssen Sie sie wie gezeigt aufteilen und dann jeden "Abschnitt" in sein ASCII-Äquivalent konvertieren.
Das Erhalten der vier Teile ist mit etwas Bit-Magie leicht zu bewerkstelligen, insbesondere mit einer Rechtsverschiebung, um den Teil, an dem wir interessiert sind, in die ersten vier Bits zu verschieben, und dann das Ergebnis mit 0xf, um es vom Rest zu isolieren. Folgendes meine ich (angenommen, wir wollen die 3 nehmen):
0xa31f -> shift right by 8 = 0x00a3 -> AND with 0xf = 0x0003
Jetzt, da wir eine einzelne Zahl haben, müssen wir sie in ihren ASCII-Wert umwandeln. Wenn die Zahl kleiner oder gleich 9 ist, können wir einfach den ASCII-Wert von 0 (0x30) hinzufügen, wenn sie größer als 9 ist, müssen wir den ASCII-Wert von a verwenden (0x61).
Hier ist es, jetzt müssen wir es nur noch codieren:
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: Ich weiß, dass dies ein 16-Bit-Code ist, aber ich verwende immer noch das alte TASM :P
PPS: dies ist die Intel-Syntax, die Konvertierung in die AT&T-Syntax ist jedoch nicht schwierig, siehe hier.