### Author Topic: How do you convert a binary number to ASCII decimal digits?  (Read 35093 times)

#### JoeCoder

• Jr. Member
• Posts: 72
• Country:
##### How do you convert a binary number to ASCII decimal digits?
« on: June 15, 2011, 01:31:44 PM »
Is there a standard way to do this or does everybody roll his own?
If you can't code it in assembly, it can't be coded!

#### Keith Kanios

• Full Member
• Posts: 383
• Country:
##### Re: How do you convert a binary number to ASCII decimal digits?
« Reply #1 on: June 15, 2011, 03:14:48 PM »
The x86 has minimal support for assisting this in the form of AAA and friends, but those are not available in long mode.

There are other ways to do this. One pure data way on the x86 would be to use a 256 byte lookup table and XLATB.

In general, it is a roll-your-own (or someone else's) situation... with emphasis on optimization (mostly eliminating inner loops) depending on how generic (e.g. printf) the conversion process needs to be.
« Last Edit: June 15, 2011, 03:16:50 PM by Keith Kanios »

#### JoeCoder

• Jr. Member
• Posts: 72
• Country:
##### Re: How do you convert a binary number to ASCII decimal digits?
« Reply #2 on: June 15, 2011, 05:43:45 PM »
Thanks Keith.
If you can't code it in assembly, it can't be coded!

#### avcaballero

• Full Member
• Posts: 132
• Country:
##### Re: How do you convert a binary number to ASCII decimal digits?
« Reply #3 on: June 27, 2011, 11:37:31 AM »
; avch
; A simple example. Surely it could be vastly enhanced
; FASM sintax
use16
org 100h
mov bx, 10
@MainLoop:
mov si, CRLF
mov ax, word [Number]
@InnerLoop:
dec si
xor dx, dx
div bx
or dl, 30h
mov byte [si], dl
or ax, ax
jnz @InnerLoop
mov dx, si
mov ah, 9
int 21h
dec word [Number]
jnz @MainLoop
ret
Number dw 0FFFFh
Text rb(7)
CRLF db 13, 10, "\$"
; Execute with:
; w2ascii > Numbers.txt

#### JoeCoder

• Jr. Member
• Posts: 72
• Country:
##### Re: How do you convert a binary number to ASCII decimal digits?
« Reply #4 on: June 27, 2011, 06:08:30 PM »
thank you
If you can't code it in assembly, it can't be coded!

#### Frank Kotler

• NASM Developer
• Hero Member
• Posts: 2667
• Country:
##### Re: How do you convert a binary number to ASCII decimal digits?
« Reply #5 on: June 28, 2011, 04:56:31 PM »
There are a lot of different ways to do this. This isn't particularly "good", but it's what I usually use.

Code: [Select]
`;---------------------------------; showeaxd - print a decimal representation of eax to stdout; for "debug purposes only"... mostly; expects: number in eax; returns: nothing useful;--------------------------------------showeaxd:    push eax    push ebx    push ecx    push edx    push esi        sub esp, 10h ; an arbitrary "round number"    lea ecx, [esp + 12]  ; another arbitrary number    mov ebx, 10  ; we want to divide by 10    xor esi, esi  ; counter    mov byte [ecx], 0 ; why do I do this? I dunno..top:        dec ecx    xor edx, edx    div ebx    add dl, '0'    mov [ecx], dl    inc esi    or eax, eax    jnz .top        mov edx, esi    mov ebx, 1    mov eax, 4    int 80h        add esp, 10h    pop esi    pop edx    pop ecx    pop ebx    pop eax    ret;---------------------------------`
I'll be posting other methods, as the spirit moves me. I have on my drive a "fast" method written by Terje Mathison. Depends on multiplying by the reciprocal instead of the "div" (which is very slow). It is in the form of an "inline asm" C function. Needs a little "tweaking" before it's ready to post... and I really ought to figure out how it works! Not right now...

Best,
Frank

#### Frank Kotler

• NASM Developer
• Hero Member
• Posts: 2667
• Country:
##### Re: How do you convert a binary number to ASCII decimal digits?
« Reply #6 on: June 28, 2011, 05:09:42 PM »
This is not strictly "on topic" for this thread, as it "goes the other way" - from ascii digits to a number. Happened to have it on hand...

Code: [Select]
`;-------------------; atoi - converts string to (unsigned!) integer; expects: buffer in edx; returns: number in eax - carry-flag set; if a non-digit (except 0 and linefeed) was encounteredatoi:    push ecx    push edx    xor eax, eax        ; clear "result".top:    movzx ecx, byte [edx]    inc edx    cmp ecx, byte 0    jz .done    cmp ecx, byte 10    jz .done        cmp ecx, byte '0'    jb .invalid    cmp ecx, byte '9'    ja .invalid        ; we have a valid character - multiply    ; result-so-far by 10, subtract '0'    ; from the character to convert it to    ; a number, and add it to result.        lea eax, [eax + eax * 4]    lea eax, [eax * 2 + ecx - '0']    jmp short .top.invalid:    stc.done:    pop edx    pop ecx    ret;--------------`
This should be called "atou", not "atoi". Change it if you care.

Best,
Frank

#### JoeCoder

• Jr. Member
• Posts: 72
• Country:
##### Re: How do you convert a binary number to ASCII decimal digits?
« Reply #7 on: June 30, 2011, 08:52:44 AM »
Thanks Frank and everybody else. I'm in the middle of a bunch of stuff and haven't had time to get back to x86 for awhile. I hope I can soon. I was looking at AAA as I believe Keith suggested. I will look over your examples when I can. thanks to everybody for the help. Nice group of people!
If you can't code it in assembly, it can't be coded!

#### ReturnInfinity

• Jr. Member
• Posts: 3
##### Re: How do you convert a binary number to ASCII decimal digits?
« Reply #8 on: July 15, 2011, 04:58:43 PM »
I use the following in 64-bit mode:

; -----------------------------------------------------------------------------
; os_int_to_string -- Convert a binary interger into an string
;  IN:   RAX = binary integer
;   RDI = location to store string
; OUT:   RDI = points to end of string
;   All other registers preserved
; Min return value is 0 and max return value is 18446744073709551615 so your
; string needs to be able to store at least 21 characters (20 for the digits
; and 1 for the string terminator).
; Adapted from http://www.cs.usfca.edu/~cruse/cs210s09/rax2uint.s
os_int_to_string:
push rdx
push rcx
push rbx
push rax

mov rbx, 10               ; base of the decimal system
xor ecx, ecx               ; number of digits generated
os_int_to_string_next_divide:
xor edx, edx               ; RAX extended to (RDX,RAX)
div rbx                  ; divide by the number-base
push rdx               ; save remainder on the stack
inc rcx                  ; and count this remainder
cmp rax, 0               ; was the quotient zero?
jne os_int_to_string_next_divide      ; no, do another division

os_int_to_string_next_digit:
pop rax                  ; else pop recent remainder
add al, '0'               ; and convert to a numeral
stosb                  ; store to memory-buffer
loop os_int_to_string_next_digit      ; again for other remainders
xor al, al
stosb                  ; Store the null terminator at the end of the string

pop rax
pop rbx
pop rcx
pop rdx
ret
; -----------------------------------------------------------------------------

; -----------------------------------------------------------------------------
; os_string_to_int -- Convert a string into a binary interger
;  IN:   RSI = location of string
; OUT:   RAX = integer value
;   All other registers preserved
; Adapted from http://www.cs.usfca.edu/~cruse/cs210s09/uint2rax.s
os_string_to_int:
push rsi
push rdx
push rcx
push rbx

xor eax, eax         ; initialize accumulator
mov rbx, 10         ; decimal-system's radix
os_string_to_int_next_digit:
mov cl, [rsi]         ; fetch next character
cmp cl, '0'         ; char preceeds '0'?
jb os_string_to_int_invalid   ; yes, not a numeral
cmp cl, '9'         ; char follows '9'?
ja os_string_to_int_invalid   ; yes, not a numeral
mul rbx            ; ten times prior sum
and rcx, 0x0F         ; convert char to int
add rax, rcx         ; add to prior total
inc rsi            ; advance source index
jmp os_string_to_int_next_digit   ; and check another char

os_string_to_int_invalid:
pop rbx
pop rcx
pop rdx
pop rsi
ret
; -----------------------------------------------------------------------------

#### Keith Kanios

• Full Member
• Posts: 383
• Country:
##### Re: How do you convert a binary number to ASCII decimal digits?
« Reply #9 on: July 15, 2011, 06:43:08 PM »
Yeesh... code blocks plz...

#### brethren

• Jr. Member
• Posts: 28
##### Re: How do you convert a binary number to ASCII decimal digits?
« Reply #10 on: July 16, 2011, 07:35:48 PM »
i posted a really fast signed dword to ascii routine
http://forum.nasm.us/index.php?topic=1042.0

challenge: just for kicks can anyone make a faster version
« Last Edit: July 16, 2011, 07:40:15 PM by brethren »

#### avcaballero

• Full Member
• Posts: 132
• Country:
##### Re: How do you convert a binary number to ASCII decimal digits?
« Reply #11 on: August 03, 2011, 06:39:04 AM »
A venerable mathematician said: "If I cannot draw it, it is that I do not understand it". Okay, life is too short to hook your routines in an example , although with no doubt that it is faster than mine. I let you an example in MS-DOS that prints 65535*2 signed numbers in 2.56 seconds inside DosBOX.

Greetings from Madrid