flat assembler
Message board for the users of flat assembler.

Index > Main > converting to string a dword max value

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 12 Jun 2010, 23:22
I was making a integer to string convertion routine but i had a problem.

The code can convert up to dword signed value (2147483647) but not unsigned value (4294967295, or 2147483648+).

what's missing?

Code:
org 100h

        mov  eax, 2147483647 ; 2147483648  4294967295 ## try these
        mov  esi, buf
        call .ToStringInDecimal
        jmp  print

 ; Convert EAX value to string in Decimal
 ;  EAX -> value
 ;  ESI -> string buffer
.ToStringInDecimal:
        xor  ecx, ecx
        mov  ebx, 10            ; decimal
    @@: cdq
        div  ebx
        push edx                ; store remainder
        inc  ecx                ; string lenght counter
        test eax, eax
        jnz  @b

    @@: pop  ebx                ; reload
        add  ebx, '0'           ; ascii offset
        mov  byte[esi+eax], bl
        inc  eax
        cmp  eax, ecx
        jne  @b

        mov  byte[esi+ecx], '$' ; end string
     ret

print:
        ; print

        mov ah, 9h
        mov dx, buf
        int 21h

        ; wait key

        mov ah, 1h
        int 21h

        ; exit

        int 20h


        buf db 11 dup ?
    


[edit:] weird line removed

_________________
Sorry if bad english.


Last edited by Teehee on 12 Jun 2010, 23:29; edited 1 time in total
Post 12 Jun 2010, 23:22
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1903
DOS386 12 Jun 2010, 23:27
Code:
        fchs    


WtF ???

Otherwise the code looks fine to me (no test) Neutral
Post 12 Jun 2010, 23:27
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 12 Jun 2010, 23:29
opsss hehe it was just a test.. im going to edit that.. sorry..
Post 12 Jun 2010, 23:29
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1903
DOS386 12 Jun 2010, 23:30
In some of my examples you can find a slightly better routine Smile

Code:
        mov  eax, 2147483647 
    


FASM is the only assembler also accepting for better readability:

Code:
        mov  eax, 2'147'483'647 
    


PS: please don't bump this one http://board.flatassembler.net/topic.php?t=10984
Post 12 Jun 2010, 23:30
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 12 Jun 2010, 23:40
where can I find your examples?

what do you mean? =O

_________________
Sorry if bad english.
Post 12 Jun 2010, 23:40
View user's profile Send private message Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
windwakr 12 Jun 2010, 23:42
Code:
  @@: cdq 
    



to

Code:
  @@: xor edx,edx
    


IIRC, cdq is signed.

_________________
----> * <---- My star, won HERE
Post 12 Jun 2010, 23:42
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1903
DOS386 12 Jun 2010, 23:45
> where can I find your examples?

Main and DOS subforums, http://board.flatassembler.net/topic.php?t=7277 , ...

> IIRC, cdq is signed.

Right: http://pdos.csail.mit.edu/6.828/2007/readings/i386/CWD.htm
Post 12 Jun 2010, 23:45
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 12 Jun 2010, 23:48
ohh nice, thank you windwakr. Now it works Very Happy

But why do i need to clear EDX? DIV does not fill it ?

PS: IIRC?


Last edited by Teehee on 12 Jun 2010, 23:56; edited 1 time in total
Post 12 Jun 2010, 23:48
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1903
DOS386 12 Jun 2010, 23:56
> PS: IIRC?

Code:
   MOV AL, 0
   IIRC
   UD2
    


http://www.google.com/search?hl=en&q=IIRC

> But why do i need to clear EDX?

DIV uses EAX and EDX as dividend, RTFM Smile

> DIV does not fill it ?

It does, but ...

http://pdos.csail.mit.edu/6.828/2007/readings/i386/DIV.htm


Last edited by DOS386 on 12 Jun 2010, 23:59; edited 2 times in total
Post 12 Jun 2010, 23:56
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 12 Jun 2010, 23:58
thanks. Smile
Post 12 Jun 2010, 23:58
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 13 Jun 2010, 12:23
what about this one:

Code:
 ; Convert EAX value to string in Decimal
 ;  EAX -> value
 ;  ECX -> string size (remember add the end char '$' space)
 ;  ESI -> string buffer
ToStringInDecimal_zeroFilled:
        mov  ebx, 10            ; decimal
        mov  byte[esi+ecx], '$' ; end string
    @@: xor  edx, edx
        div  ebx
        add  edx, '0'           ; ascii offset
        dec  ecx                ; string lenght [de]counter
        mov  byte[esi+ecx], dl
        jnz  @b
     ret    

Maybe not faster to small numbers, but it has a small size (however, it also has zero filled)
Post 13 Jun 2010, 12:23
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 13 Jun 2010, 12:26
talking about speed... how can I see if a routine is faster than another? is there a good speed counter routine?
Post 13 Jun 2010, 12:26
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4347
Location: Now
edfed 13 Jun 2010, 12:41
Code:
rdtsc
mov ebx,eax
call testfunction
rdtsc
sub eax,ebx
call printeax
    
Post 13 Jun 2010, 12:41
View user's profile Send private message Visit poster's website Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 13 Jun 2010, 12:55
unbelievable Shocked

thanks edfed Smile

_________________
Sorry if bad english.
Post 13 Jun 2010, 12:55
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 13 Jun 2010, 14:44
I have this:
Code:
String:
.EAXToStringInDecimal:
        mov  ebx, 10            ; decimal
        xor  ecx, ecx
    @@: xor  edx, edx
        div  ebx
        push edx                ; store remainder
        inc  ecx                ; string lenght counter
        test eax, eax
        jnz  @b
    @@: pop  ebx                ; reload
        add  ebx, '0'           ; ascii offset
        mov  byte[esi+eax], bl
        inc  eax
        cmp  eax, ecx
        jne  @b
        mov  byte[esi+eax], '$' ; end string
     ret      

and in another function i'd like to jump to the first @@ in the function above.
Code:
.EAXToStringInBinary:
        mov  ebx, 2             ; binary
        jmp .EAXToStringInDecimal.@@ ;something like this    

Which options do I have?

_________________
Sorry if bad english.
Post 13 Jun 2010, 14:44
View user's profile Send private message Reply with quote
edemko



Joined: 18 Jul 2009
Posts: 549
edemko 13 Jun 2010, 15:05
Post 13 Jun 2010, 15:05
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 13 Jun 2010, 19:19
Teehee,

If you jump there, ecx counter won't be properly initialized. To refer local label out of its locality scope, use something like String.EAXToStringInX.
Post 13 Jun 2010, 19:19
View user's profile Send private message Reply with quote
Teehee



Joined: 05 Aug 2009
Posts: 570
Location: Brazil
Teehee 13 Jun 2010, 22:42
its ok i'm doing in another way.

here my lib about convert uInt to String in Binary, Decimal and Hexadecimal:
Code:
String:

; ## Convert EAX value to string in Binary format ##
;  + EAX -> value
;  + ESI -> string buffer (must have at least 11 bytes wide)
.EAXToStringInBinary:
        mov  ebx, 2             ; binary
        jmp  @f                 ; go to .EAXToStringInDecimal.@@

; ## Convert EAX value to string in Decimal format ##
;  + EAX -> value to convert
;  + ESI -> string buffer (must have at least 11 bytes wide)
.EAXToStringInDecimal:
        mov  ebx, 10            ; decimal
    @@: xor  ecx, ecx
    @@: xor  edx, edx
        div  ebx
        push edx                ; store remainder
        inc  ecx                ; string lenght counter
        test eax, eax
        jnz  @b
    @@: pop  ebx                ; reload remainder
        add  ebx, '0'           ; ascii offset
        mov  byte[esi+eax], bl
        inc  eax
        cmp  eax, ecx
        jne  @b
        mov  byte[esi+eax], '$' ; end string
     ret

; ## Convert EAX value to string in Binary format with zero filled ##
;  + EAX -> value to convert
;  + ECX -> string size   (remember to add terminator char '$' space)
;  + ESI -> string buffer (must have <string size> size)
.EAXToStringInBinary_zeroFilled:
        mov  ebx, 2             ; binary
        jmp  @f                 ; go to .EAXToStringInDecimal_zeroFilled.@@

; ## Convert EAX value to string in Decimal format with zero filled ##
;  + EAX -> value to convert
;  + ECX -> string size   (remember to add terminator char '$' space)
;  + ESI -> string buffer (must have <string size> size)
.EAXToStringInDecimal_zeroFilled:
        mov  ebx, 10            ; decimal
    @@: mov  byte[esi+ecx], '$' ; end string
    @@: xor  edx, edx
        div  ebx
        add  edx, '0'           ; ascii offset
        dec  ecx                ; string lenght [de]counter
        mov  byte[esi+ecx], dl
        jnz  @b
     ret

; ## Convert EAX value to string in Hexadecimal format ##
;  + EAX -> value to convert
;  + ESI -> string buffer (must have at least 11 bytes wide)
.EAXToStringInHexa:
        mov  ebx, 16            ; Hexadecimal
        xor  ecx, ecx
    @@: xor  edx, edx
        div  ebx
        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:
        push edx                ; store remainder
        inc  ecx                ; string lenght counter
        test eax, eax
        jnz @b
    @@: pop  ebx                ; reload remainder
        mov  byte[esi+eax], bl
        inc  eax
        cmp  eax, ecx
        jne @b
        mov  byte[esi+eax], '$' ; end string
     ret

; ## Convert EAX value to string in Hexadecimal format with zero filled ##
;  + EAX -> value to convert
;  + ECX -> string size   (remember to add terminator char '$' space)
;  + ESI -> string buffer (must have <string size> size)
.EAXToStringInHexa_zeroFilled:
        mov  ebx, 16            ; decimal
        mov  byte[esi+ecx], '$' ; end string
    @@: xor  edx, edx
        div  ebx
        cmp  edx, 10            ; 10 = A
        jae .hexf
        add  edx, '0'           ; ascii offset
        jmp .skipHexf
 .hexf: add  edx, '7'           ; Hex offset (A,B,C,D,E,F)
 .skipHexf:
        dec  ecx                ; string lenght [de]counter
        mov  byte[esi+ecx], dl
        jnz  @b
     ret
    

Any optimization are welcome.
Post 13 Jun 2010, 22:42
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 14 Jun 2010, 01:38
Teehee,

The most obvious size optimization is merging .EAXToStringInDecimal with .EAXToStringInHexa (similar to .EAXToStringInBinary / .EAXToStringInDecimal synergy).

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).

If you'll keep .EAXToStringInHexa separate from .EAXToStringInDecimal, there are probably many ways how it can be improved.
Post 14 Jun 2010, 01:38
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 14 Jun 2010, 04:25
Teehee wrote:
talking about speed... how can I see if a routine is faster than another?
The short, and more accurate, answer is "You can't (on any of the modern x86 processors)"

Testing speed, while it sounds easy, is not easy at all, especially for short routines. You will have a very hard time to discover the real speed of execution. And not only that, the execution time changes depending upon the previous and the following instructions in the instruction queue.
Post 14 Jun 2010, 04:25
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.