flat assembler
Message board for the users of flat assembler.

Index > Main > dword to ascii, ascii to dword

Goto page 1, 2, 3, 4  Next
Author
Thread Post new topic Reply to topic
sleepsleep



Joined: 05 Oct 2006
Posts: 8898
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
i found the following, maybe anyone got "stock" ascii to dword implementation?

very happy to use brethren code =)
Quote:

8 times faster than the comparable C function



thank you.

fast signed dword to ascii conversion
http://forum.nasm.us/index.php?topic=1042.0

Code:
;---------------------------------------------------------------------------
proc stringNum2A uses ebx esi edi ecx edx, num
;---------------------------------------------------------------------------
        mov  eax,[num]
        mov  ebx,_stringNum2A
        ; or you add another ebx param to this procedure and load it using
        ; mov  ebx,[_numBuffer]
        mov  esi, 0xCCCCCCCD
        test eax,eax
        jns  .calcNumOfDigits
        
        mov  byte [ebx],'-'
        inc  ebx
        neg  eax

        .calcNumOfDigits:
                cmp  eax,9
                ja   @f
                inc  ebx
                jmp  .terminateString
        @@:
                cmp  eax,99
                ja   @f
                add  ebx,2
                jmp  .terminateString
        @@:
                cmp  eax,999
                ja   @f
                add  ebx,3
                jmp  .terminateString
        @@:
                cmp  eax,9999
                ja   @f
                add  ebx,4
                jmp  .terminateString
        @@:
                cmp  eax,99999
                ja   @f
                add  ebx,5
                jmp  .terminateString
        @@:
                cmp  eax,999999
                ja   @f
                add  ebx,6
                jmp  .terminateString
        @@:
                cmp  eax,9999999
                ja   @f
                add  ebx,7
                jmp  .terminateString
        @@:
                cmp  eax,99999999
                ja   @f
                add  ebx,8
                jmp  .terminateString
        @@:
                cmp  eax,999999999
                ja   @f
                add  ebx,9
                jmp  .terminateString
        @@:
                add  ebx,10
        
        .terminateString:
                mov  byte [ebx],0
                dec  ebx
                
        .doConversion:
                mov  ecx,eax
                mul  esi
                shr  edx,3
                mov  eax,edx
                lea  edx,[edx+edx*4]
                lea  edx,[edx+edx-'0']
                sub  ecx,edx
                
                mov  [ebx],cl
                sub  ebx,1
                test eax,eax
                jz   .finish
                
                mov  ecx,eax
                mul  esi
                shr  edx,3
                mov  eax,edx
                lea  edx,[edx+edx*4]
                lea  edx,[edx+edx-'0']
                sub  ecx,edx
                mov  [ebx],cl
                sub  ebx,1
                test eax,eax
                jnz  .doConversion
        .finish:
        ret
endp
    
Post 08 Feb 2013, 08:51
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
All these comparisons and unpredicted jumps forward are faster? Really?..
I doubt it.
Post 08 Feb 2013, 11:27
View user's profile Send private message Send e-mail Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
> All these comparisons and unpredicted jumps forward are faster? Really?.. I doubt it.

Do you really have performance problems with integer <-> decimal ???

http://board.flatassembler.net/topic.php?t=11321
http://forum.nasm.us/index.php?topic=454.0

WtF Very Happy

(someone move it to Main please)
Post 08 Feb 2013, 13:30
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 8898
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
i dont have performance problem,
but since i want to use it, might as well find one that travel lightspeed,

how true is the claim, idk, i just copy paste exactly as what the coder believe.
Post 08 Feb 2013, 14:28
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
In theory, jumps forward are not recommended by the manuals.
I am talking about Intel, of course.
Post 08 Feb 2013, 14:29
View user's profile Send private message Send e-mail Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 8898
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
ok, i found this on masm forum,
benchmark for DWORD to ASCII algorithm,
bmtemplate4
http://masm32.com/board/index.php?topic=208.0

it is posted by hutch-- (aka administrator)

(unsigned value only!)
Quote:

Intel(R) Core(TM)2 Duo CPU T7500 @ 2.20GHz
Results 8 pass average
timing Ray original utoa 310 ms
timing Paul Dixon utoa_ex 109 ms
timing brethren utoa2 218 ms
timing Lingo utoa_ex 93 ms
timing msvc ustr$ 727 ms
timing Ray modified utoa3 300 ms


Lingo utoa_ex algo
Code:
utoa_ex proc uvar:DWORD,pbuffer:DWORD

  ; --------------------------------------------------------------------------------
  ; this algorithm was written by Paul Dixon and has been converted to MASM notation
  ; --------------------------------------------------------------------------------

    mov eax, [esp+4]                ; uvar      : unsigned variable to convert
    mov ecx, [esp+8]                ; pbuffer   : pointer to result buffer

    push esi
    push edi

    jmp udword

  align 4
  chartab:
    dd "00","10","20","30","40","50","60","70","80","90"
    dd "01","11","21","31","41","51","61","71","81","91"
    dd "02","12","22","32","42","52","62","72","82","92"
    dd "03","13","23","33","43","53","63","73","83","93"
    dd "04","14","24","34","44","54","64","74","84","94"
    dd "05","15","25","35","45","55","65","75","85","95"
    dd "06","16","26","36","46","56","66","76","86","96"
    dd "07","17","27","37","47","57","67","77","87","97"
    dd "08","18","28","38","48","58","68","78","88","98"
    dd "09","19","29","39","49","59","69","79","89","99"

  udword:
    mov esi, ecx                    ; get pointer to answer
    mov edi, eax                    ; save a copy of the number

    mov edx, 0D1B71759h             ; =2^45\10000    13 bit extra shift
    mul edx                         ; gives 6 high digits in edx

    mov eax, 68DB9h                 ; =2^32\10000+1

    shr edx, 13                     ; correct for multiplier offset used to give better accuracy
    jz short skiphighdigits         ; if zero then don't need to process the top 6 digits

    mov ecx, edx                    ; get a copy of high digits
    imul ecx, 10000                 ; scale up high digits
    sub edi, ecx                    ; subtract high digits from original. EDI now = lower 4 digits

    mul edx                         ; get first 2 digits in edx
    mov ecx, 100                    ; load ready for later

    jnc short next1                 ; if zero, supress them by ignoring
    cmp edx, 9                      ; 1 digit or 2?
    ja   ZeroSupressed              ; 2 digits, just continue with pairs of digits to the end

    mov edx, chartab[edx*4]         ; look up 2 digits
    mov [esi], dh                   ; but only write the 1 we need, supress the leading zero
    inc esi                         ; update pointer by 1
    jmp  ZS1                        ; continue with pairs of digits to the end

  align 16
  next1:
    mul ecx                         ; get next 2 digits
    jnc short next2                 ; if zero, supress them by ignoring
    cmp edx, 9                      ; 1 digit or 2?
    ja   ZS1a                       ; 2 digits, just continue with pairs of digits to the end

    mov edx, chartab[edx*4]         ; look up 2 digits
    mov [esi], dh                   ; but only write the 1 we need, supress the leading zero
    add esi, 1                      ; update pointer by 1
    jmp  ZS2                        ; continue with pairs of digits to the end

  align 16
  next2:
    mul ecx                         ; get next 2 digits
    jnc short next3                 ; if zero, supress them by ignoring
    cmp edx, 9                      ; 1 digit or 2?
    ja   ZS2a                       ; 2 digits, just continue with pairs of digits to the end

    mov edx, chartab[edx*4]         ; look up 2 digits
    mov [esi], dh                   ; but only write the 1 we need, supress the leading zero
    add esi, 1                      ; update pointer by 1
    jmp  ZS3                        ; continue with pairs of digits to the end

  align 16
  next3:

  skiphighdigits:
    mov eax, edi                    ; get lower 4 digits
    mov ecx, 100

    mov edx, 28F5C29h               ; 2^32\100 +1
    mul edx
    jnc short next4                 ; if zero, supress them by ignoring
    cmp edx, 9                      ; 1 digit or 2?
    ja  short ZS3a                  ; 2 digits, just continue with pairs of digits to the end

    mov edx, chartab[edx*4]         ; look up 2 digits
    mov [esi], dh                   ; but only write the 1 we need, supress the leading zero
    inc esi                         ; update pointer by 1
    jmp short  ZS4                  ; continue with pairs of digits to the end

  align 16
  next4:
    mul ecx                         ; this is the last pair so don; t supress a single zero
    cmp edx, 9                      ; 1 digit or 2?
    ja  short ZS4a                  ; 2 digits, just continue with pairs of digits to the end

    mov edx, chartab[edx*4]         ; look up 2 digits
    mov [esi], dh                   ; but only write the 1 we need, supress the leading zero
    mov byte ptr [esi+1], 0         ; zero terminate string

    pop edi
    pop esi
    ret 8

  align 16
  ZeroSupressed:
    mov edx, chartab[edx*4]         ; look up 2 digits
    mov [esi], dx
    add esi, 2                      ; write them to answer

  ZS1:
    mul ecx                         ; get next 2 digits
  ZS1a:
    mov edx, chartab[edx*4]         ; look up 2 digits
    mov [esi], dx                   ; write them to answer
    add esi, 2

  ZS2:
    mul ecx                         ; get next 2 digits
  ZS2a:
    mov edx, chartab[edx*4]         ; look up 2 digits
    mov [esi], dx                   ; write them to answer
    add esi, 2

  ZS3:
    mov eax, edi                    ; get lower 4 digits
    mov edx, 28F5C29h               ; 2^32\100 +1
    mul edx                         ; edx= top pair
  ZS3a:
    mov edx, chartab[edx*4]         ; look up 2 digits
    mov [esi], dx                   ; write to answer
    add esi, 2                      ; update pointer

  ZS4:
    mul ecx                         ; get final 2 digits
  ZS4a:
    mov edx, chartab[edx*4]         ; look them up
    mov [esi], dx                   ; write to answer

    mov byte ptr [esi+2], 0         ; zero terminate string

  sdwordend:

    pop edi
    pop esi

    ret 8

utoa_ex endp
    
Post 09 Feb 2013, 04:43
View user's profile Send private message Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode
Quote:
Intel(R) Core(TM)2 Quad CPU Q8300 @ 2.50GHz
Results 8 pass average
timing Ray original utoa 298 ms
timing Paul Dixon utoa_ex 97 ms
timing brethren utoa2 220 ms
timing Lingo utoa_ex 95 ms
timing msvc ustr$ 501 ms
timing Ray modified utoa3 306 ms
lingo wins (as usual)
thanks for sharing
Cheers,
Very Happy

_________________
⠓⠕⠏⠉⠕⠙⠑
Post 09 Feb 2013, 07:50
View user's profile Send private message Visit poster's website Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 8898
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
anyone ascii to dword?

signed (-8888) & unsigned (8888) ?

INPUT = asciiAddr ( address of ascii string number to be translated into register)
PROCESS = if first byte is "-" that it is signed, otherwise, unsigned
OUTPUT = EAX

anyone? we make a test?
Post 09 Feb 2013, 12:29
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
What is "8 pass average"?
How the number "95ms" was received?
Post 09 Feb 2013, 13:03
View user's profile Send private message Send e-mail Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 8898
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
Code:
iterate equ <10000000>      ; benchmark loop count
algo_delay equ <50>        ; ms delay between each algo timing

invoke GetTickCount
push eax
invoke GetTickCount
pop ecx
sub eax, ecx
    
Post 09 Feb 2013, 13:10
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1180
Location: Unknown
HaHaAnonymous
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 21:38; edited 1 time in total
Post 09 Feb 2013, 15:19
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 8898
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
string1 db '-56',0
string 2 db '8943',0
string3 db '-898432',0

load those string, parse them, put value into EAX, return EAX

i will attach a file that got 1000 string to get parse.
then we could benchmark using that file.
Post 09 Feb 2013, 15:26
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1180
Location: Unknown
HaHaAnonymous
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 21:38; edited 1 time in total
Post 09 Feb 2013, 15:33
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
@2sleep: also how the code called must be defined.
Is it a function? or just piece of code to copy/paste?
If it is a function - what is calling convention?

Also, GetTickCount() is a bad way to measure the code speed.
Use QueryPerformanceTimer() instead.
Post 09 Feb 2013, 15:35
View user's profile Send private message Send e-mail Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 8898
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
Code:
stdcall yournick_ascii2d, string1

proc yournick_ascii2d asciiAddr
   ret
endp
    
Post 09 Feb 2013, 15:44
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1180
Location: Unknown
HaHaAnonymous
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 21:38; edited 1 time in total
Post 09 Feb 2013, 15:48
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 8898
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
ah, i mean, name your procedure as HaHaAnonymous_ascii2d if you want to join this game =)

return EAX, thats it...

sampel input

1,000,000 unique ascii string number - 5MB+-
http://www.sinimari.com/ascii.7z

those who wanna play =) please use same input file. thank you
Code:
string1 db '-1131117056',0
string2 db '-2749744128',0
string3 db '4131544576',0
string4 db '-3121858560',0
string5 db '-4018176512',0
string6 db '1004735488',0
string7 db '-862578176',0
string8 db '4021784576',0
string9 db '-1535281664',0
string10        db '3677705216',0
    


Last edited by sleepsleep on 09 Feb 2013, 19:25; edited 2 times in total
Post 09 Feb 2013, 16:00
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1180
Location: Unknown
HaHaAnonymous
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 21:38; edited 1 time in total
Post 09 Feb 2013, 16:03
View user's profile Send private message Reply with quote
sleepsleep



Joined: 05 Oct 2006
Posts: 8898
Location: ˛                             ⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣⁣Posts: 334455
sleepsleep
i think i need to modify the input file,

since the maximum negative value a register could have is -2147483648 (i tested with wsprintf %ld) true or not, am not sure.

i will re-update the input file with negative value less or equal to -2147483648
Post 09 Feb 2013, 18:42
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1180
Location: Unknown
HaHaAnonymous
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 21:38; edited 1 time in total
Post 09 Feb 2013, 18:52
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2, 3, 4  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar.

Powered by rwasa.