News:

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

Converting a decimal number to ascci (dwtoa)

Started by RuiLoureiro, November 17, 2008, 07:02:16 PM

Previous topic - Next topic

RuiLoureiro

Hi,
I used dwtoa (masm32) and from dwtoa i wrote CnvToRcl and ddToRcl.
With CnvToRcl i know the string length and it seems to give better results.
CnvToRcl uses push to the stack
ddToRcl  is CnvToRcl but saves registers in mmx

Is there any other idea that gives better results ?
What are the results do you get with this code ?
Thanks.
Rui


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
    .586
    .mmx   
    include \masm32\macros\timers.asm

CnvToRcl    proto :DWORD,:DWORD
ddToRcl     proto :DWORD,:DWORD
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
_data0      dd 7FFFFFFFh       ;0FFFFFFFFh
_data1      dd 70000000h       ;4294967295
_data2      dd 0FF9FF8Fh       ;3232323299
_data3      dd 00FF8F9Fh
_data4      dd 000F8F91h
_data5      dd 00008F91h
_data6      dd 10
_data7      dd 1255780
_data8      dd 0
_data9      dd 0FFFFFFFFh

            dd 20               ; -8   max. string length
            dd 0                ; -4   string length
_buffer0    db 20 dup (0)
            db 0                ; can end with 0
            ;
            dd 20
            dd 0
_buffer1    db 20 dup (0)
            db 0
           
            dd 20
            dd 0
_buffer2    db 20 dup (0)
            db 0
           
            dd 20
            dd 0
_buffer3    db 20 dup (0)
            db 0
           
            dd 6    ; 6          <-  with 6 the next buffer is protected
            dd 0                   ; using CnvToRcl
_buffer4    db 6 dup (0)
            db 0

            db 10 dup (0)           ; protection

            dd 9               
            dd 0
_buffer5    db 9 dup (0)
            db 0
           
            dd 20
            dd 0
_buffer6    db 20 dup (0)
            db 0           

            dd 20
            dd 0
_buffer7    db 20 dup (0)
            db 0           

            dd 20
            dd 0
_buffer8    db 20 dup (0)
            db 0           

            dd 20
            dd 0
_buffer9    db 20 dup (0)
            db 0                       
    .code
; ##########################################
start:
    ;invoke Sleep, 40
; ##########################################
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data0, offset _buffer0 

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "     

    print   offset _buffer0, 13, 10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data1, offset _buffer1

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "

    print   offset _buffer1, 13, 10
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data2, offset _buffer2

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "

    print   offset _buffer2, 13, 10
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data3, offset _buffer3

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "

    print   offset _buffer3, 13, 10
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data4, offset _buffer4

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "
    print   offset _buffer4, 13, 10
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data5, offset _buffer5

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "
    print   offset _buffer5, 13, 10   
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data6, offset _buffer6

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "
    print   offset _buffer6, 13, 10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data7, offset _buffer7

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "
    print   offset _buffer7, 13, 10   
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data8, offset _buffer8

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "
    print   offset _buffer8, 13, 10   
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data9, offset _buffer9

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "
    print   offset _buffer9, 13, 10   
       
    print   chr$(13, 10)
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  CnvToRcl, _data0, offset _buffer0

    counter_end
    print ustr$(eax)," cycles ", "CnvToRcl  "
   
    print   offset _buffer0, 13, 10
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  CnvToRcl, _data1, offset _buffer1

    counter_end
    print ustr$(eax)," cycles ", "CnvToRcl  "
   
    print   offset _buffer1, 13, 10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  CnvToRcl, _data2, offset _buffer2

    counter_end
    print ustr$(eax)," cycles ", "CnvToRcl  "
   
    print   offset _buffer2, 13, 10
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  CnvToRcl, _data3, offset _buffer3

    counter_end
    print ustr$(eax)," cycles ", "CnvToRcl  "
   
    print   offset _buffer3, 13, 10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  CnvToRcl, _data4, offset _buffer4

    counter_end
    print ustr$(eax)," cycles ", "CnvToRcl  "
   
    print   offset _buffer4, 13, 10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  CnvToRcl, _data5, offset _buffer5

    counter_end
    print ustr$(eax)," cycles ", "CnvToRcl  "   
    print   offset _buffer5, 13, 10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  CnvToRcl, _data6, offset _buffer6

    counter_end
    print ustr$(eax)," cycles ", "CnvToRcl  "   
    print   offset _buffer6, 13, 10           
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  CnvToRcl, _data7, offset _buffer7

    counter_end
    print ustr$(eax)," cycles ", "CnvToRcl  "   
    print   offset _buffer7, 13, 10           
; «««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  CnvToRcl, _data8, offset _buffer8

    counter_end
    print ustr$(eax)," cycles ", "CnvToRcl  "   
    print   offset _buffer8, 13, 10           
; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  CnvToRcl, _data9, offset _buffer9

    counter_end
    print ustr$(eax)," cycles ", "CnvToRcl  "   
    print   offset _buffer9, 13, 10 
    print   chr$(13, 10)   
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  ddToRcl, _data0, offset _buffer0

    counter_end
    print ustr$(eax)," cycles ", "ddToRcl  "
   
    print   offset _buffer0, 13, 10
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  ddToRcl, _data1, offset _buffer1

    counter_end
    print ustr$(eax)," cycles ", "ddToRcl  "
   
    print   offset _buffer1, 13, 10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  ddToRcl, _data2, offset _buffer2

    counter_end
    print ustr$(eax)," cycles ", "ddToRcl  "
   
    print   offset _buffer2, 13, 10
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  ddToRcl, _data3, offset _buffer3

    counter_end
    print ustr$(eax)," cycles ", "ddToRcl  "
   
    print   offset _buffer3, 13, 10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  ddToRcl, _data4, offset _buffer4

    counter_end
    print ustr$(eax)," cycles ", "ddToRcl  "
   
    print   offset _buffer4, 13, 10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  ddToRcl, _data5, offset _buffer5

    counter_end
    print ustr$(eax)," cycles ", "ddToRcl  "   
    print   offset _buffer5, 13, 10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  ddToRcl, _data6, offset _buffer6

    counter_end
    print ustr$(eax)," cycles ", "ddToRcl  "   
    print   offset _buffer6, 13, 10           
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  ddToRcl, _data7, offset _buffer7

    counter_end
    print ustr$(eax)," cycles ", "ddToRcl  "   
    print   offset _buffer7, 13, 10           
; «««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  ddToRcl, _data8, offset _buffer8

    counter_end
    print ustr$(eax)," cycles ", "ddToRcl  "   
    print   offset _buffer8, 13, 10           
; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  ddToRcl, _data9, offset _buffer9

    counter_end
    print ustr$(eax)," cycles ", "ddToRcl  "   
    print   offset _buffer9, 13, 10 
         
;----------------------------------------------------
    print   chr$(13, 10)   
    inkey "Press any key to exit..."
    exit
   
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««
align 4
dwtoa proc dwValue:DWORD, lpBuffer:DWORD
    push ebx
    push esi
    push edi

    mov eax, dwValue
    mov edi, [lpBuffer]

    test eax,eax
    jnz  sign

  zero:
    mov word ptr [edi],30h
    jmp dtaexit
    ;
    ; Removed for unsigned numbers
    ;
  sign:     
;    jns pos
;    mov byte ptr [edi],'-'
;    neg eax
;    add edi, 1

  pos:
    mov ecx, 3435973837
    mov esi, edi

    .while (eax > 0)
      mov ebx,eax
      mul ecx
      shr edx, 3
      mov eax,edx
      lea edx,[edx*4+edx]
      add edx,edx
      sub ebx,edx
      add bl,'0'
      mov [edi],bl
      add edi, 1
    .endw

    mov byte ptr [edi], 0       ; terminate the string

    ; We now have all the digits, but in reverse order.

    .while (esi < edi)
      sub edi, 1
      mov al, [esi]
      mov ah, [edi]
      mov [edi], al
      mov [esi], ah
      add esi, 1
    .endw

  dtaexit:

    pop edi
    pop esi
    pop ebx
    ret
dwtoa endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
align 16
CnvToRcl    proc    Val:DWORD, pBuf:DWORD
            push    ebx
            push    esi
            push    edi

            mov     eax, [esp+16]           ; Val
            mov     edi, [esp+20]           ; pBuf

            test    eax, eax
            jnz     short @F
           
            mov     dword ptr [edi - 4], 1
            mov     word ptr [edi], 30h
            jz      _exit

@@:
            mov     ecx, 3435973837
            xor     esi, esi
                       
@@:             mov     ebx, eax
                mul     ecx
                shr     edx, 3
                mov     eax, edx
                lea     edx, [edx*4+edx]
                add     edx, edx
                sub     ebx, edx
                add     bl, '0'
                ;
                push    ebx                 ; To stack
                add     esi, 1
            or      eax, eax
            jnz     short @B
           
            ;»»»»»» Buffer length control »»»»»»»»»»
            cmp     esi, dword ptr [edi - 8]
            jbe     short _go
            ;
@@:         pop     eax                         ; Get from stack
            sub     esi, 1
            jnz     short @B           
           
            mov     dword ptr [edi - 4], 0
            mov     byte ptr [edi], 0           ; terminate the string
            stc           
            jc      short _exit
            ;»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
           
_go:        mov     dword ptr [edi - 4], esi
                         
@@:         pop     eax                         ; Get from stack
            mov     byte ptr [edi], al
            add     edi, 1
            sub     esi, 1
            jnz     short @B           

            mov     byte ptr [edi], 0           ; terminate the string
            clc
           
_exit:      pop     edi
            pop     esi
            pop     ebx
            ret     8
CnvToRcl    endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
align 16
ddToRcl     proc    Val:DWORD, pBuf:DWORD

            movd    mm0, ebx
            movd    mm1, esi
            movd    mm2, edi

            mov     eax, [esp+4]           ; Val
            mov     edi, [esp+8]           ; pBuf

            test    eax, eax
            jnz     short @F
           
            mov     dword ptr [edi - 4], 1
            mov     word ptr [edi], 30h
            jz      _exit

@@:
            mov     ecx, 3435973837
            xor     esi, esi
                       
@@:             mov     ebx, eax
                mul     ecx
                shr     edx, 3
                mov     eax, edx
                lea     edx, [edx*4+edx]
                add     edx, edx
                sub     ebx, edx
                add     bl, '0'
                ;
                push    ebx                 ; To stack
                add     esi, 1
            or      eax, eax
            jnz     short @B
           
            ;»»»»»» Buffer length control »»»»»»»»»»
            cmp     esi, dword ptr [edi - 8]
            jbe     short _go
            ;
@@:         pop     eax                         ; Get from stack
            sub     esi, 1
            jnz     short @B           
           
            mov     dword ptr [edi - 4], 0
            mov     byte ptr [edi], 0           ; terminate the string
            stc           
            jc      short _exit
            ;»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
           
_go:        mov     dword ptr [edi - 4], esi
                         
@@:         pop     eax                         ; Get from stack
            mov     byte ptr [edi], al
            add     edi, 1
            sub     esi, 1
            jnz     short @B           

            mov     byte ptr [edi], 0           ; terminate the string
            clc
           
_exit:     
            movd    ebx, mm0
            movd    esi, mm1
            movd    edi, mm2

            ret     8
ddToRcl     endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


Quote
;dwtoa with sign control
;**********************
;195 cycles dwtoa  2147483647             178 cycles CnvToRcl  2147483647
;197 cycles dwtoa  1879048192             179 cycles CnvToRcl  1879048192
;186 cycles dwtoa  268042127              161 cycles CnvToRcl  268042127
;159 cycles dwtoa  16748447               208 cycles CnvToRcl  16748447
;144 cycles dwtoa  1019793                130 cycles CnvToRcl  1019793 
;104 cycles dwtoa  36753                  98  cycles CnvToRcl  36753
;49  cycles dwtoa  10                     47  cycles CnvToRcl  10
;144 cycles dwtoa  1255780                129 cycles CnvToRcl  1255780
;19  cycles dwtoa  0                      19  cycles CnvToRcl  0
;37  cycles dwtoa  -1                     182 cycles CnvToRcl  4294967295

;Press any key to exit...
;-----------------------------------------------------------
; dwtoa without sign control
; *************************
;195 cycles dwtoa 2147483647           183 cycles CnvToRcl  2147483647
;201 cycles dwtoa  1879048192           183 cycles CnvToRcl  1879048192
;189 cycles dwtoa  268042127            164 cycles CnvToRcl  268042127
;164 cycles dwtoa  16748447             153 cycles CnvToRcl  16748447
;144 cycles dwtoa  1019793              134 cycles CnvToRcl  1019793
;106 cycles dwtoa  36753                98  cycles CnvToRcl  36753
;52  cycles dwtoa  10                   47  cycles CnvToRcl  10
;144 cycles dwtoa  1255780              128 cycles CnvToRcl  1255780
;20  cycles dwtoa  0                    18  cycles CnvToRcl  0
;196 cycles dwtoa  4294967295           182 cycles CnvToRcl  4294967295

;177 cycles ddToRcl  2147483647
;177 cycles ddToRcl  1879048192
;160 cycles ddToRcl  268042127
;150 cycles ddToRcl  16748447
;124 cycles ddToRcl
;94  cycles ddToRcl  36753
;44  cycles ddToRcl  10
;127 cycles ddToRcl  1255780
;12  cycles ddToRcl  0
;176 cycles ddToRcl  4294967295

;Press any key to exit...

RuiLoureiro

#1
I want to count the number of decimal digits in the EAX register
I used NumDigEAX and CountDigEAX

Is there any other idea that gives better results ?
What are the results do you get with this code ?
Thanks.
Rui

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
    .686
    .mmx
    include \masm32\macros\timers.asm
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
_data0      dd 7FFFFFFFh       ;0FFFFFFFFh
_data1      dd 70000000h       ;4294967295
_data2      dd 0FF9FF8Fh       ;3232323299
_data3      dd 00FF8F9Fh
_data4      dd 000F8F91h
_data5      dd 00008F91h
_data6      dd 10
_data7      dd 1255780
_data8      dd 0
_data9      dd 0FFFFFFFFh

            dd 20               ; -8   max. string length
            dd 0                ; -4   string length
_buffer0    db 20 dup (0)
            db 0                ; can end with 0
            ;
            dd 20
            dd 0
_buffer1    db 20 dup (0)
            db 0
           
            dd 20
            dd 0
_buffer2    db 20 dup (0)
            db 0
           
            dd 20
            dd 0
_buffer3    db 20 dup (0)
            db 0
           
            dd 6    ; 6          <-  with 6 the next buffer is protected
            dd 0                   ; using CnvToRcl
_buffer4    db 6 dup (0)
            db 0

            db 10 dup (0)           ; protection

            dd 9               
            dd 0
_buffer5    db 9 dup (0)
            db 0
           
            dd 20
            dd 0
_buffer6    db 20 dup (0)
            db 0           

            dd 20
            dd 0
_buffer7    db 20 dup (0)
            db 0           

            dd 20
            dd 0
_buffer8    db 20 dup (0)
            db 0           

            dd 20
            dd 0
_buffer9    db 20 dup (0)
            db 0                       
    .code
; ###############################################
start:
    ;invoke Sleep, 40
; #################################################
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data0, offset _buffer0 

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "     

    print   offset _buffer0, 13, 10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data1, offset _buffer1

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "

    print   offset _buffer1, 13, 10
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data2, offset _buffer2

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "

    print   offset _buffer2, 13, 10
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data3, offset _buffer3

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "

    print   offset _buffer3, 13, 10
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data4, offset _buffer4

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "
    print   offset _buffer4, 13, 10
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data5, offset _buffer5

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "
    print   offset _buffer5, 13, 10   
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data6, offset _buffer6

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "
    print   offset _buffer6, 13, 10
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data7, offset _buffer7

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "
    print   offset _buffer7, 13, 10   
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data8, offset _buffer8

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "
    print   offset _buffer8, 13, 10   
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    invoke  dwtoa, _data9, offset _buffer9

    counter_end
    print ustr$(eax)," cycles ", "dwtoa  "
    print   offset _buffer9, 13, 10   
       
    print   chr$(13, 10)
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data0
    call    NumDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "NumDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data1
    call    NumDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "NumDigEAX  "
    print ustr$(edi), 13, 10           
   
; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data2
    call    NumDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "NumDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data3
    call    NumDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "NumDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data4
    call    NumDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "NumDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data5
    call    NumDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "NumDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data6
    call    NumDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "NumDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data7
    call    NumDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "NumDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data8
    call    NumDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "NumDigEAX  "
    print ustr$(edi), 13, 10           
; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data9
    call    NumDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "NumDigEAX  "
    print ustr$(edi), 13, 10 
    print   chr$(13, 10)       
;+++++++++++++++++++++++++++++++++++++++++++++++++++++
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data0
    call    CountDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "CountDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data1
    call    CountDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "CountDigEAX  "
    print ustr$(edi), 13, 10           
   
; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data2
    call    CountDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "CountDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data3
    call    CountDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "CountDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data4
    call    CountDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "CountDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data5
    call    CountDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "CountDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data6
    call    CountDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "CountDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data7
    call    CountDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "CountDigEAX  "
    print ustr$(edi), 13, 10           

; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data8
    call    CountDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "CountDigEAX  "
    print ustr$(edi), 13, 10           
; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data9
    call    CountDigEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "CountDigEAX  "
    print ustr$(edi), 13, 10
    print   chr$(13, 10)             
;+++++++++++++++++++++++++++++++++++++++++++++++++++++
; ««««««««««««««««««««««««««««««««««««««««««««««««««««
    counter_begin 1000000, HIGH_PRIORITY_CLASS

    mov     eax, _data9
    call    DigCountEAX
    mov     edi, ecx
   
    counter_end
    print ustr$(eax)," cycles ", "DigCountEAX  "
    print ustr$(edi), 13, 10 

;----------------------------------------------------
    print   chr$(13, 10)   
    inkey "Press any key to exit..."
    exit
   
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««
align 4
dwtoa proc dwValue:DWORD, lpBuffer:DWORD
    push ebx
    push esi
    push edi

    mov eax, dwValue
    mov edi, [lpBuffer]

    test eax,eax
    jnz  sign

  zero:
    mov word ptr [edi],30h
    jmp dtaexit
    ;
    ; Removed for unsigned numbers
    ;
  sign:     
;    jns pos
;    mov byte ptr [edi],'-'
;    neg eax
;    add edi, 1

  pos:
    mov ecx, 3435973837
    mov esi, edi

    .while (eax > 0)
      mov ebx,eax
      mul ecx
      shr edx, 3
      mov eax,edx
      lea edx,[edx*4+edx]
      add edx,edx
      sub ebx,edx
      add bl,'0'
      mov [edi],bl
      add edi, 1
    .endw

    mov byte ptr [edi], 0       ; terminate the string

    ; We now have all the digits, but in reverse order.

    .while (esi < edi)
      sub edi, 1
      mov al, [esi]
      mov ah, [edi]
      mov [edi], al
      mov [esi], ah
      add esi, 1
    .endw

  dtaexit:

    pop edi
    pop esi
    pop ebx
    ret
dwtoa endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; Output:
;           ECX     - nº de dígitos
;
align 16
NumDigEAX   proc   
            push    eax
            push    ebx
            push    edx
            push    esi
   
            test    eax, eax
            jnz     short @F

            mov     esi, 1
            jz      _exit

@@:
            mov     ecx, 3435973837
            xor     esi, esi
                       
@@:             mov     ebx, eax
                mul     ecx
                shr     edx, 3
                mov     eax, edx
                lea     edx, [edx*4+edx]
                add     edx, edx
                sub     ebx, edx
                add     bl, '0'
                ;
                add     esi, 1
               
            or      eax, eax
            jnz     short @B
                               
_exit:      mov     ecx, esi
            ;           
            pop     esi
            pop     edx
            pop     ebx
            pop     eax
            ret
NumDigEAX   endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; Output:
;           ECX     - nº de dígitos
;
align 16
CountDigEAX proc   

            movd    mm0, eax
            movd    mm1, ebx
            movd    mm2, edx
            movd    mm3, esi
   
            test    eax, eax
            jnz     short @F

            mov     esi, 1
            jz      _exit

@@:
            mov     ecx, 3435973837
            xor     esi, esi
                       
@@:             mov     ebx, eax
                mul     ecx
                shr     edx, 3
                mov     eax, edx
                lea     edx, [edx*4+edx]
                add     edx, edx
                sub     ebx, edx
                add     bl, '0'
                ;
                add     esi, 1
               
            or      eax, eax
            jnz     short @B
                               
_exit:      mov     ecx, esi
            ;
            movd    eax, mm0
            movd    ebx, mm1
            movd    edx, mm2
            movd    esi, mm3
            ret
CountDigEAX endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««
align 16
DigCountEAX proc
push     eax
                  push      ebx
                  push      edx
;
mov     ebx, 10
xor     ecx, ecx
jz     short _next           
;
@@:               xor     edx, edx
div     ebx
add     ecx, 1
;
_next:            or     eax, eax
jnz     short @B             
;
                  pop     edx
                  pop       ebx
                  pop       eax
ret
DigCountEAX endp
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


Quote
;195 cycles NumDigEAX  10       144 cycles CountDigEAX  10
;196 cycles NumDigEAX  10       146 cycles CountDigEAX  10
;180 cycles NumDigEAX  9        130 cycles CountDigEAX  9
;163 cycles NumDigEAX  8        116 cycles CountDigEAX  8
;148 cycles NumDigEAX  7        101 cycles CountDigEAX  7
;122 cycles NumDigEAX  5        74  cycles CountDigEAX  5
;34  cycles NumDigEAX  2        31  cycles CountDigEAX  2
;150 cycles NumDigEAX  7        102 cycles CountDigEAX  7
;14  cycles NumDigEAX  1        9   cycles CountDigEAX  1
;192 cycles NumDigEAX  10       145 cycles CountDigEAX  10


;631 cycles DigCountEAX  10

;Press any key to exit...

MichaelW

#2
Hi Rui,

Here is a quick attempt at a fast digit counting procedure. I did not have time to try and optimize it.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
    .686
    include \masm32\macros\timers.asm
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
align 4
digits proc
    mov edx, eax
    xor eax, eax
    N=10
    REPEAT 9
      inc eax
      cmp edx, N
      jb  @F
      N=N*10
    ENDM
    inc eax
  @@:
    ret
digits endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
   
    N=1
    REPEAT 10
      print ustr$(N)," "
      mov eax, N
      call digits
      print ustr$(eax),13,10
      N=N*10
    ENDM
    print chr$(13,10)

    invoke Sleep, 3000

    N=1
    REPEAT 10
      print ustr$(N)," "
      counter_begin 1000, HIGH_PRIORITY_CLASS
        mov eax, N
        call digits
      counter_end
      print ustr$(eax)," cycles",13,10
      N=N*10
    ENDM

    print chr$(13,10)

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


Here is the code generated for the procedure:

00401000                    fn_00401000:
00401000 8BD0                   mov     edx,eax
00401002 33C0                   xor     eax,eax
00401004 40                     inc     eax
00401005 83FA0A                 cmp     edx,0Ah
00401008 7246                   jb      loc_00401050
0040100A 40                     inc     eax
0040100B 83FA64                 cmp     edx,64h
0040100E 7240                   jb      loc_00401050
00401010 40                     inc     eax
00401011 81FAE8030000           cmp     edx,3E8h
00401017 7237                   jb      loc_00401050
00401019 40                     inc     eax
0040101A 81FA10270000           cmp     edx,2710h
00401020 722E                   jb      loc_00401050
00401022 40                     inc     eax
00401023 81FAA0860100           cmp     edx,186A0h
00401029 7225                   jb      loc_00401050
0040102B 40                     inc     eax
0040102C 81FA40420F00           cmp     edx,0F4240h
00401032 721C                   jb      loc_00401050
00401034 40                     inc     eax
00401035 81FA80969800           cmp     edx,989680h
0040103B 7213                   jb      loc_00401050
0040103D 40                     inc     eax
0040103E 81FA00E1F505           cmp     edx,5F5E100h
00401044 720A                   jb      loc_00401050
00401046 40                     inc     eax
00401047 81FA00CA9A3B           cmp     edx,3B9ACA00h
0040104D 7201                   jb      loc_00401050
0040104F 40                     inc     eax
00401050                    loc_00401050:
00401050 C3                     ret


And here are the results on my P3:

1 1
10 2
100 3
1000 4
10000 5
100000 6
1000000 7
10000000 8
100000000 9
1000000000 10

1 3 cycles
10 3 cycles
100 5 cycles
1000 7 cycles
10000 7 cycles
100000 11 cycles
1000000 12 cycles
10000000 13 cycles
100000000 15 cycles
1000000000 14 cycles


Edit:

I made the obvious optimization of removing the last comparison and conditional jump.
eschew obfuscation

RuiLoureiro

Hi all,

Hello MichaelW !
                        Thank you !
                         We dont need quick attemps, Michael . We have time to do it, may be tommorow !
                         Or tommorrow ... Thank you

                         MichaelW, what can we do with mmx registers ? movd, movq and what else ?
                         
      Could anyone test digitos2.exe (see bellow) and show the results here
Thanks
Rui

Here are my results on P4 XP, sp3:
Quote
35  cycles dwtoa  9
49  cycles dwtoa  99
69  cycles dwtoa  999
85  cycles dwtoa  9999
107 cycles dwtoa  99999
122 cycles dwtoa  999999
144 cycles dwtoa  9999999
158 cycles dwtoa  99999999
181 cycles dwtoa  999999999
41  cycles dwtoa  -1

20  cycles NumDigEAX  1
35  cycles NumDigEAX  2
86  cycles NumDigEAX  3
109 cycles NumDigEAX  4
122 cycles NumDigEAX  5
136 cycles NumDigEAX  6
150 cycles NumDigEAX  7
163 cycles NumDigEAX  8
176 cycles NumDigEAX  9
191 cycles NumDigEAX  10

17  cycles CountDigEAX  1
31  cycles CountDigEAX  2
44  cycles CountDigEAX  3
59  cycles CountDigEAX  4
73  cycles CountDigEAX  5
87  cycles CountDigEAX  6
102 cycles CountDigEAX  7
115 cycles CountDigEAX  8
130 cycles CountDigEAX  9
145 cycles CountDigEAX  10

621 cycles DigCountEAX  10

9  cycles CountDigits  1
5  cycles CountDigits  2
11 cycles CountDigits  3
9  cycles CountDigits  4
9  cycles CountDigits  5
14 cycles CountDigits  6
15 cycles CountDigits  7
17 cycles CountDigits  8
20 cycles CountDigits  9
17 cycles CountDigits  10

8  cycles CountDigit  1
9  cycles CountDigit  2
6  cycles CountDigit  3
11 cycles CountDigit  4
10 cycles CountDigit  5
13 cycles CountDigit  6
15 cycles CountDigit  7
12 cycles CountDigit  8
17 cycles CountDigit  9
13 cycles CountDigit  10

8  cycles digits  1
9  cycles digits  2
6  cycles digits  3
9  cycles digits  4
10 cycles digits  5
12 cycles digits  6
16 cycles digits  7
16 cycles digits  8
20 cycles digits  9
17 cycles digits  10

Press any key to exit...



[attachment deleted by admin]

Grincheux

Here are the results on my Intel Celeron CPU E1200 at 1.60Ghz
Ram : 3Gb - Video Card : NVIDIA GeForce 7300 LE


19 cycles dwtoa  9
26 cycles dwtoa  99
35 cycles dwtoa  999
43 cycles dwtoa  9999
54 cycles dwtoa  99999
61 cycles dwtoa  999999
70 cycles dwtoa  9999999
76 cycles dwtoa  99999999
90 cycles dwtoa  999999999
19 cycles dwtoa  -1

5 cycles NumDigEAX  1
11 cycles NumDigEAX  2
18 cycles NumDigEAX  3
27 cycles NumDigEAX  4
35 cycles NumDigEAX  5
45 cycles NumDigEAX  6
52 cycles NumDigEAX  7
62 cycles NumDigEAX  8
79 cycles NumDigEAX  9
85 cycles NumDigEAX  10

5 cycles CountDigEAX  1
12 cycles CountDigEAX  2
19 cycles CountDigEAX  3
28 cycles CountDigEAX  4
36 cycles CountDigEAX  5
45 cycles CountDigEAX  6
53 cycles CountDigEAX  7
62 cycles CountDigEAX  8
73 cycles CountDigEAX  9
84 cycles CountDigEAX  10

299 cycles DigCountEAX  10

2 cycles CountDigits  1
3 cycles CountDigits  2
3 cycles CountDigits  3
4 cycles CountDigits  4
4 cycles CountDigits  5
5 cycles CountDigits  6
6 cycles CountDigits  7
7 cycles CountDigits  8
8 cycles CountDigits  9
8 cycles CountDigits  10

2 cycles CountDigit  1
3 cycles CountDigit  2
2 cycles CountDigit  3
4 cycles CountDigit  4
4 cycles CountDigit  5
5 cycles CountDigit  6
6 cycles CountDigit  7
7 cycles CountDigit  8
8 cycles CountDigit  9
8 cycles CountDigit  10

2 cycles digits  1
3 cycles digits  2
3 cycles digits  3
4 cycles digits  4
4 cycles digits  5
5 cycles digits  6
6 cycles digits  7
7 cycles digits  8
8 cycles digits  9
8 cycles digits  10

Press any key to exit...


These results are more than correct for me.

Kenavo

Grincheux
_____________________________________________________
http://www.phrio.biz

raymond

The subject of determining the number of decimal digits for a hex number came up on the other board. You may want to try the procedure I proposed. It is applicable to integers up to 64 bits. It is based on lookup tables and should definitely be much quicker.

http://www.asmcommunity.net/board/index.php?topic=29155.new;topicseen#new
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com