News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Binary to Dec/Hex

Started by Eric4ever, April 10, 2006, 08:30:45 AM

Previous topic - Next topic

Eric4ever

how to convert a binary number to a Dec or Hex number? Is there a classic method?

and who can explain the HexToDec snippet for me,THX

xor eax,eax
mov ebx,16
.while TRUE
movzx ecx,byte ptr [esi]
inc esi
.break .if ! ecx
.if cl > '9'
sub cl,'A' - 0ah
.else
sub cl,'0'
.endif
mul ebx
add eax,ecx
.endw

Tedd

There are many methods - some simple, some overly complex (apparently in the name of speed) - but basically the principle is the same: take each 'digit' and convert it to the correspnoding character. (Generally a case of dividing by the base, and taking the remainder for the next step.)

Your example code:
- get first character
- if zero (end of string): exit
- if character is above '9' (assumed to then be character 'A'-'Z'): convert it to its value ('A'=10, 'B'=11, ..., 'F'=15)
   else (assume is a digit): convert to value ('0'=0, '1'=1, ..., '9'=9)
- take that value, and mutliply it by 16 (hex is base 16)
- add the result onto total
- go back to the start of the loop for the next character

It could be improved a little, and made more robust, but will work as long as nothing goes wrong :lol
Where did you steal it from? :bdg
No snowflake in an avalanche feels responsible.

Wistrik

#2
I have a routine at home that does it without any jumps. I'll post it when I get off work later today.

Update: oops, it's a hex ASCII to binary converter. I'll still post it though for fun. AL contains the ASCII digit (0..9, A..F) going in, and AL contains the binary nybble coming out. Could probably be unrolled using 32-bit registers in order to process two digits at a time, or 64-bit registers for four digits, though I haven't researched it. I'm just copying from an old piece of code I had laying around. My programming has gotten rusty in the last decade so I've forgotten how it works. I like it because it avoids expensive jumps, is compact and fast.
add al,40h
cbw
and ah,09h
add al,ah
and al,0Fh

If all else fails, search the web (that's how I find almost all the answers to my questions). AMD publishes a binary to decimal ASCII converter (with or without leading zeros) in their optimization guide.

Eric4ever


skywalker

Quote from: Eric4ever on April 10, 2006, 08:30:45 AM
how to convert a binary number to a Dec or Hex number? Is there a classic method?

and who can explain the HexToDec snippet for me,THX


This code shows you how to convert to the 3 most common you'll see in assembly.


; eax2dec.asm  Convert the value in eax into decimal, hexadecimal,
;              and binary values

.model tiny
.386
.code

org 100h

begin:
     jmp        start

decimal   db      ' (decimal)$'
hex       db      'h (hex)$'
binary    db      'b (binary)$'

start:
     mov eax, 1234567890   ; 1,234,567,890

     call eax2dec
     call newline
     call eax2hex
     call newline
     call eax2bin

     mov ax, 4C00h
     int 21h

eax2dec:
     push eax
     push ebx
     push cx
     push edx

     mov ebx, 10         ; divide by ten
     xor cx, cx          ; zero our counter

push_digit:
     xor edx, edx        ; clear dx for the div - use cwd and
     div ebx             ; idiv for signed numbers
     push dx             ; save remainder
     inc cx              ; bump digit counter
     or eax, eax         ; is quotient zero?
     jnz push_digit      ; no, do more

     mov ah, 2           ; print character subfunction

pop_digit:
     pop dx              ; get remainder back
     add dl, '0'         ; convert to ascii character
     int 21h             ; print it
     loop pop_digit      ; cx times

     pop edx
     pop cx
     pop ebx
     pop eax
     lea        dx,decimal     
     mov        ah,9
     int        21h
     ret

eax2hex:
     push cx
     push dx

     mov cx, 8           ; eight digits to show

top:
     rol eax, 4          ; rotate one digit into position
     mov dl, al          ; make a copy to process
     and dl, 0Fh         ; mask off a single (hex) digit
     cmp dl, 9           ; is it in the 'A' to 'F' range?
     jbe dec_dig        ; no, skip it
     add dl, 7           ; adjust

dec_dig:
     add dl, 30h         ; convert to character

     push ax
     mov ah, 2           ; print the character
     int 21h
     pop ax

     loop top

     pop dx
     pop cx

     lea        dx,hex
     mov        ah,9
     int        21h
     ret

eax2bin:
     push cx
     push dx
     mov cx, 32    ; 32 binary digits
top1:
     rcl eax, 1    ; rotate and set/clear carry
     mov dl, '0'
     adc dl, 0     ; make it '1' if carry set

     push ax
     mov ah, 2     ; print it
     int 21h
     pop ax

     loop top1

     pop dx
     pop cx
     lea        dx,binary
     mov        ah,9
     int        21h
     ret

newline:
     push ax
     push dx

     mov ah, 2       ; print character in dl
     mov dl, 13      ; carriage return
     int 21h
     mov dl, 10      ; and linefeed
     int 21h

     pop dx
     pop ax
     ret
end     begin