flat assembler
Message board for the users of flat assembler.

Index > Main > converting to string a dword max value

Goto page Previous  1, 2
Author
Thread Post new topic Reply to topic
Picnic



Joined: 05 May 2007
Posts: 1404
Location: Piraeus, Greece
Picnic 14 Jun 2010, 16:22
Just spicing up topic a little more, this time by using a stack frame.

Code:
            push 0FFFFFFFFh             ; number
            push 10                     ; BASE  (0-36)
            push szBuffer                ; buffer PTR 
            call Num2Str


 Num2Str:
            enter 0, 0                  ; create stack frame
            pushad                      ; save registers
            pushfd                      ; save flags
            cld
            mov edi, [ebp+08h]          ; buffer PTR
            mov ebx, [ebp+0Ch]          ; BASE
            mov eax, [ebp+10h]          ; number
            xor ecx, ecx
.push:      xor edx, edx
            div ebx                     ; number / base
            push edx                    ; push the remainder
            inc ecx                     ; increase the "digit-count"
            test eax, eax               ; if the quotient still is not 0, do it once more
            jnz .push
.pop:       pop eax                     ; pop the remainder
            add al, 30h                 ; convert the number to a character
            cmp al, '9'
            jng .nq                     ; if the charater is greater than "9" then we have
            add al, 07h                 ; to add 7 to get A as 10, B as 11, and so on...
.nq:        stosb                       ; store digit
            loop .pop
            xor al, al                  ; NULL terminate buffer
            stosb                       ;
            popfd                       ; restore flags
            popad                       ; restore registers
            leave
            ret 0Ch
    
Post 14 Jun 2010, 16:22
View user's profile Send private message Visit poster's website Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 14 Jun 2010, 17:35
baldr wrote:
The most obvious size optimization is merging .EAXToStringInDecimal with .EAXToStringInHexa (similar to .EAXToStringInBinary / .EAXToStringInDecimal synergy).

Indeed, I saw now i can put the three functions together.

Quote:
if-then-else structure in .EAXToStringInHexa can be converted to if-then (lea edx, [edx+'0'] leaves eflags intact). It can even be branchless (CF is useful).

oh.. indeed, i changed this:
Code:
        cmp  edx, 10            ; 10 = A
        jae  .hex
        add  edx, '0'           ; ascii offset
        jmp  .skipHex
  .hex: add  edx, '7'           ; Hex offset (A,B,C,D,E,F)
  .skipHex:     

by this:
Code:
        cmp  edx, 10            ; 10 = A
        jnae .skpHx
        add  edx, 'A'-'9'-1     ; Hex offset (A,B,C,D,E,F)
 .skpHx:add  edx, '0'           ; ascii offset      

But i don't understood the lea edx, [edx+'0'] thing. Ok, i supose its like add edx, '0'. but why i would preffer it i didn't understand.

Quote:
If you'll keep .EAXToStringInHexa separate from .EAXToStringInDecimal, there are probably many ways how it can be improved.

I'd like to know some of these improvements to improve up my knowledges. (like the tip u gave me above).

_________________
Sorry if bad english.
Post 14 Jun 2010, 17:35
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20454
Location: In your JS exploiting you and your system
revolution 14 Jun 2010, 19:12
Teehee wrote:
But i don't understood the lea edx, [edx+'0'] thing. Ok, i supose its like add edx, '0'. but why i would preffer it i didn't understand.
It depends upon whether you need to preserve the flags or not. lea doesn't alter the flags. add will alter the flags.
Post 14 Jun 2010, 19:12
View user's profile Send private message Visit poster's website Reply with quote
edemko



Joined: 18 Jul 2009
Posts: 549
edemko 14 Jun 2010, 23:17
Post 14 Jun 2010, 23:17
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 15 Jun 2010, 19:29
i didn't understand the sbb / das thing.. Sad
Post 15 Jun 2010, 19:29
View user's profile Send private message Reply with quote
edemko



Joined: 18 Jul 2009
Posts: 549
edemko 15 Jun 2010, 19:38
i was understanding the trick for 40 minutes
refer to the intel mans and own practice
Post 15 Jun 2010, 19:38
View user's profile Send private message Reply with quote
edemko



Joined: 18 Jul 2009
Posts: 549
edemko 16 Jun 2010, 17:48
feryno's tricky amazing:
http://fdbg.x86asm.net/fdbg0022.zip -> \fdbg0022\fdbg0022\fta16_hexa_proc_ftr.inc
Code:
hexa_64_rax_aligned:
; put rax value to ASCII hexadecimal 16 byte buffer at [rdi]
; rdi must be aligned 16
        bswap   rax
 movdqa  xmm3,dqword [Sum1]
  movdqa  xmm4,dqword [Comp1]
 movdqa  xmm2,dqword [Mask1]
 movdqa  xmm5,dqword [Num1]
  movq    xmm1,rax
    movdqa  xmm0,xmm1
   psrlq   xmm1,4
      pand    xmm0,xmm2
   pand    xmm1,xmm2
   punpcklbw       xmm1,xmm0
   movdqa  xmm0,xmm1
   pcmpgtb xmm1,xmm4
   pand    xmm1,xmm5
   paddb   xmm0,xmm3
   paddb   xmm0,xmm1
   movdqa  dqword [rdi],xmm0
   bswap   rax
 ret
; ...
; \fdbg0022\fdbg0022\hexa_data.inc
align 16

Sum1                   dq      3030303030303030h, 3030303030303030h
Mask1                   dq      0f0f0f0f0f0f0f0fh, 0f0f0f0f0f0f0f0fh
Comp1                   dq      0909090909090909h, 0909090909090909h
Num1                    dq      0707070707070707h, 0707070707070707h
    
Post 16 Jun 2010, 17:48
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 16 Jun 2010, 23:13
Supplemental SSE3 (Core2+) contains interesting instruction: pshufb. It can be used as SIMD 4-bit xlat.
Code:
        mov     eax, 0x76543210         ; 76'54'32'10 (numbers mean nibble index, not value)
        bswap   eax                     ; 10'32'54'76
        movd    xmm0, eax
        shr     eax, 4                  ; .1'03'25'47 (dot means insignificant zero nibble)
        movd    xmm1, eax
        punpcklbw xmm1, xmm0            ; 10'.1'32'03'54'25'76'47 (high half of xmm not shown)
        pand    xmm1, [nibble_mask]     ; .0'.1'.2'.3'.4.'5'.6'.7 (need to clear only bit 7 of each byte)
        movdqa  xmm0, [hex_digits]
        pshufb  xmm0, xmm1              ; x0'x1'x2'x3'x4'x5'x6'x7 (x# is a hex digit for nibble #)
        movq    qword[edi], xmm0

        align   16
label hex_digits dqword
        db      '0123456789ABCDEF'
label nibble_mask dqword
        db      16 dup 15    
I've used eax as a source only to make comments readable. 64-bit version requires trivial modifications.

SSE4.1 has pblendvb which can be used to improve parallelism in feryno's function (precalc nibble+'0' and nibble-10+'A', then choose latter for nibble>9).
Post 16 Jun 2010, 23:13
View user's profile Send private message Reply with quote
edemko



Joined: 18 Jul 2009
Posts: 549
edemko 23 Jun 2010, 23:50
Good night.
I was a poem.
[edit]edit:[/edit]int64 zero test fixed
Code:
/*
  enu: stores int64 into a bsa-string(bsa_new for more details).
  low        = value's low 32bits
  hi         = value's high 32bits
  options    = 00..07: non zero value will be triple separator
               31..31: 1 - value can be signed, 0 - do not
  buf35bytes = area to form a bsa-string in
  eax        <- bsa.body
  examples:
        stdcall  i2a,-1,-1,$80000000,buf35bytes
        invoke   MessageBoxA,0,eax,0,0

        stdcall  i2a,-1,-1,$00000000,buf35bytes
        invoke   MessageBoxA,0,eax,0,0

        stdcall  i2a,-1,-1,$00000020,buf35bytes
        invoke   MessageBoxA,0,eax,0,0

        stdcall  i2a,0,-1,$80000000 or "'",buf35bytes
        invoke   MessageBoxA,0,eax,0,0
*/
proc i2a; low,hi,options,buf35bytes
                                  ;2^64-1 = 18 446 744 073 709 551 615
                                  ;2^63-1 =  9 223 372 036 854 775 807
        mov      eax,[esp+4]      ;low
        xchg     ebx,[esp+8]      ;hi
        xchg     ecx,[esp+12]     ;options
        xchg     edi,[esp+16]     ;buf35bytes
        push     edx esi          ;EDX for remainder & ESI for 10
        pushfd

        add      edi,34           ;switch buf35bytes's end
        mov      ch,0
        mov      byte[edi],ch     ;put Arno; @feryno likes that film
        btr      ecx,31           ;signed mode?
        jnc      .signless
        bt       ebx,31           ;is value signed in signed mode?
        jnc      .signless
        bts      ecx,31           ;we'll look for it to put '-' soon
        not      ebx              ;negate value
        neg      eax              ;...
        sbb      ebx,-1           ;...
  .signless:
        mov      esi,10           ;thanks @Picnic for the "What's Special About This Number?.mht"
  .loop:xor      edx,edx          ;@revolution, i can divide big, thanX
        add      ch,01'000001b    ;make CF=1 at every step 4; increase stored chars count
        jnc      .not_triple
        cmp      cl,dl
        cmovnz   edx,ecx          ;put user triple separator
        jnz      .store
    .not_triple:
        xchg     eax,ebx
        div      esi              ;div hi
        xchg     eax,ebx
        div      esi              ;div low
        add      dl,'0'           ;0..9 -> '0'..'9'
    .store:
        dec      edi              ;<-rise bsa header<-
        mov      [edi],dl
        MOV      EDX,EAX          ;test int64 for zero
        OR       EDX,EBX          ;...
        jnz      .loop
        bt       ecx,31           ;so, has '-' been?
        jnc      .store_bsa_header
        inc      ch               ;increase digit count
        dec      edi
        mov      byte[edi],'-'    ;mayonnaise, hi @ouadji, hi @edfed
  .store_bsa_header:
        and      ch,00'111111b    ;drop CF bits
        movzx    ecx,ch
        mov      [edi-4],ecx      ;bsa.body_len
        inc      eax
        mov      [edi-8],eax      ;bsa.ref_count = 1
        mov      eax,edi          ;bsa.body

        popfd
        pop      esi edx
        mov      edi,[esp+16]
        mov      ecx,[esp+12]
        mov      ebx,[esp+8]
        ret      16               ;i've been disconnected 2 times, so won't edit
endp
    
Post 23 Jun 2010, 23:50
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2

< 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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.