Today I needed a function to convert a decimal string (8 bit ascii) into a binary value with 64-bit precision.
OA32 didn't have one, so I threw this together.
If anyone feels like writing a better version, I'll replace it... but it seems to work ok for what I needed.


;Cheap and nasty proc to convert decimal string to QWORD in EDX::EAX

.data
multipliers qword 1, 10, 100, 1000, 10000, 100000,1000000,10000000,100000000,1000000000,10000000000
qword 100000000000,1000000000000,10000000000000,100000000000000,1000000000000000
qword 10000000000000000, 100000000000000000, 1000000000000000000, 10000000000000000000
.code
dec2qword proc uses esi ebx pString
LOCAL Accum:qword
LOCAL sign, cnt

qdmov Accum,0
mov sign,+1
mov esi, pString
.if byte ptr=="-"
mov sign,-1
inc esi
.elseif byte ptr=="+"
inc esi
.endif
invoke lstrlen,esi
add esi,eax
dec esi
mov cnt,eax

xor ebx,ebx
.while ebx<cnt
push ebx
mov eax,ebx
shl eax,3 ;*sizeof qword
lea edx, multipliers
add eax,edx
mov edx,.QuadWord.HiDWord
mov eax,.QuadWord.LoDWord
push eax
movzx eax,byte ptr
sub al,30h
mov ebx,eax
pop eax
qdmul
qqadd Accum, edx::eax
dec esi
pop ebx
inc ebx
.endw
.if sign==-1
mov eax,Accum.QuadWord.LoDWord
mov edx,Accum.QuadWord.HiDWord
mov Accum.QuadWord.LoDWord,0
mov Accum.QuadWord.HiDWord,0
qqsub Accum, edx::eax
.endif
mov eax,Accum.QuadWord.LoDWord
mov edx,Accum.QuadWord.HiDWord
ret
dec2qword endp

Posted on 2010-04-28 05:18:13 by Homer
Not claiming that mine is better, but I wrote these a few years ago. I'll just link them here for comparison's sake:
http://srcvault.scali.eu.org/cgi-bin/Syntax/Syntax.cgi?ParseRadix.asm
http://srcvault.scali.eu.org/cgi-bin/Syntax/Syntax.cgi?PrintRadix.asm

Edit: one idea that may be useful is that my routines try to use 32-bit operations where possible, and only use full 64-bit arithmetic when required.
They can also be used for any radix, so you can use this routine for binary, octal, decimal, hexadecimal etc, by simply specifying 2, 8, 10 or 16 as radix.
Posted on 2010-04-28 06:10:37 by Scali
A quick attempt:


udec2qword proc uses ebx ecx esi edi pString
xor eax,eax ; result LOW
xor edx,edx ; result HIGH


mov ebx,pString

movzx ecx,byte ptr

cmp ecx,'-'
je _negative

align 16 ; actually, better align the proc itself, and then tune the _again2 with _negative
   _again:
sub ecx,'0'
mov esi,eax
mov edi,edx
cmp ecx,9
ja _done

add eax,eax
adc edx,edx
inc ebx

shld edi,esi,3
shl  esi,3
add esi,ecx
movzx ecx,byte ptr
adc eax,esi ; ** correction, was ADD
adc edx,edi


jmp _again
_done:
ret



 _negative:
inc ebx
movzx ecx,byte ptr
align 16
   _again2:
sub ecx,'0'
mov esi,eax
mov edi,edx
cmp ecx,9
ja _done2

add eax,eax
adc edx,edx
inc ebx

shld edi,esi,3
shl  esi,3
add esi,ecx
movzx ecx,byte ptr
adc eax,esi ; **** correction. Was ADD
adc edx,edi


jmp _again2
_done2:
printh edx
printh eax

;dec eax
;sbb edx,0
;xor eax,-1
;xor edx,-1
    neg    edx ; correction 2
    neg    eax
    sbb    edx, 0


ret
udec2qword endp


The eax:edx negation needs improvement, I don't remember any ideas on how to do it.
The code is simply

int64 result=0;
while(ecx=digit){
   result = result*10 + ecx; // = result+result + (result*8) + ecx;
}



Edit: correction "add eax,esi" -> "adc eax,esi".
correction 2: fixed the 64-bit negation as baldr noted.
Posted on 2010-04-28 13:45:30 by Ultrano

The eax:edx negation needs improvement


Definitely, because dec eax leaves CF intact. ;-)
Scali's functions contain right code for 64-bit neg; my multiple-precision (i.e. additional adc/negs can follow) variant is


        neg    eax
        adc    edx, 0
        neg    edx
Posted on 2010-04-28 15:42:03 by baldr
Thanks :) . Fixed it.
Posted on 2010-04-28 15:50:35 by Ultrano