Da man mit Strings nicht rechnen kann, muss die Hexadezimalzahl erst in das
Computerformat (Dword) übertragen und daraus der Dezimalstring gebildet werden.
Es handelt sich also um eine Kombination der Hex-Int-Umwandlung
und der Int-Dez-Umwandlung .
Nasm
SEGMENT .data
hex: db "72 6B 68 62",0
SEGMENT .bss
dezz: resb 12 ; 11 Dezimalziffern + 1 Abschlussnull
SEGMENT .text
Hex2Dez:
Hex2Dword:
mov esi, hex ; Vorgabe
xor edx, edx ; Ergebnis
.Schleife:
lodsb
cmp al, '0'
jb .Leerzeichen ; keine Zahl, Leerzeichen ausprobieren
cmp al, '9'
ja .Majuskel ; keine Zahl, Großbuchstaben ausprobieren
and al, 0Fh
shl edx, 4
or dl, al
jmp .Schleife
.Leerzeichen:
cmp al, 32
je .Schleife
jmp .Hex2IntEnde
.Majuskel:
cmp al, 'A'
jb .Hex2IntEnde
cmp al, 'F'
ja .Minuskel ; kein Großbuchstabe, Kleinbuchstaben ausprobieren
sub al, 55
shl edx, 4
or dl, al
jmp .Schleife
.Minuskel:
cmp al, 'a'
jb .Hex2IntEnde
cmp al, 'f'
ja .Hex2IntEnde
sub al, 87
shl edx, 4
or dl, al
jmp .Schleife
.Hex2IntEnde: ; Ergebnis in EDX
Dword2Dez:
mov eax, edx ; Vorgabe
mov edi, dezz ; Ergebnis
mov ebx, 10 ; Divisor
xor ecx, ecx ; ECX=0 (Anzahl der Ziffern)
.Schleife_1:
xor edx, edx
div ebx ; EDX:EAX / EBX = EAX Rest EDX
push dx ; LIFO
add cl,1 ; ADD soll schneller sein als INC
or eax, eax ; AX = 0?
jnz .Schleife_1 ; nein: nochmal
.Schleife_2:
pop ax ; gepushte Ziffern zurückholen
or al, 00110000b ; Umwandlung in ASCII
stosb ; Nur AL nach [EDI] (EDI ist ein Zeiger auf den String)
loop .Schleife_2 ; bis keine Ziffern mehr da sind
mov byte [edi], 0 ; ASCIIZ-Abschlussnull
.Int2DezEnde: ; Ergebnis in [dezz]
ret