flat assembler
Message board for the users of flat assembler.

Index > Main > Numerical Format Conversions

Author
Thread Post new topic Reply to topic
pal



Joined: 26 Aug 2008
Posts: 227
pal
So I am making a calculator, and I want to be able to take input/output in various different bases (mainly decimal, hexadecimal and binary, but also octal and custom base).

So far I have come up with two codes; Hex2Dec and Bin2Dec, which are below.

Code:
 proc    Hex2Dec,szHex
               push    ebx
         push    [szHex]
             call    strlen
              
            mov             ebx,eax
             mov             ecx,eax
             dec     ebx
         mov             edi,[szHex]
         xor             edx,edx
     h2dLoop:
                dec             ecx
         jl              h2dEnd
              
            movzx   eax,byte [edi+ecx]
          sub             al,48
               cmp             al,9 ; 0-9
          jle             h2dAdd
              
            sub             al,17
               cmp             al,6 ; A-F 
         jle             @F 
         
            sub     al,32
               cmp             al,6 ; a-f
          
    @@: add             al,10
       h2dAdd: ; We need a << 4 for each position left in string (* 16)
          push    ebx
         push    edx
         push    eax
         push    ecx
         sub             ebx,ecx ; Position in string
                mov     ecx,ebx
             ; 16^ebx. We can do << 4 * ebx
                mov             eax,4
               mul             ecx ; 4 * position
          mov     ecx,eax
             mov             eax,1
               shl             eax,cl ; eax = 16^ebx
               mov     ebx,eax
             pop             ecx
         pop             eax
         xchg    eax,ebx
             mul     ebx
         test    eax,eax
             cmovz   eax,ebx ; If < 10 use original value
             pop             edx
         add             edx,eax
             pop             ebx
         jmp             h2dLoop
     
    h2dEnd:
         pop             ebx
         mov             eax,edx
             ret
 endp

    ; !!!!!! Add support for > 32 bits 
      proc    Binary2Dec,szBinary
         push    ebx
         push    edi
         push    [szBinary]
          call    strlen
              mov             ecx,eax
             mov             ebx,eax
             dec             ebx
         mov             edi,[szBinary]
              xor             edx,edx 
    b2dLoop:
                dec             ecx
         jl              b2dEnd ; Less than 0

            movzx   eax,byte [edi+ecx]
          cmp             al,0x30 ; '0'
             je              b2dLoop
             
            ; Find position of ~0 in string and calculate value 
                push    ebx
         push    edx
         sub             ebx,ecx ; ebx = position from end 
          xchg    ebx,ecx
             mov             eax,1
               shl             eax,cl ; eax *= 2 for each postition left from end
          xchg    ecx,ebx
     @@: pop             edx
         add             edx,eax
             pop             ebx
         jmp             b2dLoop
             
    b2dEnd:
         pop             edi
         pop             ebx
         mov             eax,edx
             ret
 endp
        
    proc    strlen,szString
             push    edi
         mov             edi,[szString]
              mov             edx,edi
             mov             ecx,-1
              xor             eax,eax
             repnz   scasb
               dec             edi
         xchg    eax,edi
             sub             eax,edx
             pop             edi
         ret
 endp
    


But I have a few problems.

1. They only support up to 32 bit output. I know I can output to a memory array, but I am a bit confused on how to do this properly. This is the same with the input for the other functions (e.g. Dec2Bin). Say for the Dec2Bin, I would want to input the decimal value as a string rather than an actual value as otherwise I cant go above 2^32 - 1, but how do I know how many bytes the input is? Would I have to have a parameter saying the length in bytes or something?

2. Any quick tips on the optimisation of those above codes? I know they are very sub-optimal.

3. Any links or pointers on how to do some of the other ones e.g. decimal to hexadecimal and decimal to any base.

I saw a nice tool, I think it is in the projects and ideas forum, that converts from any base to any base, but the source code is not available.

Cheers for any help, Unknown.
Post 15 Aug 2009, 23:16
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17247
Location: In your JS exploiting you and your system
revolution
1. You might want to search for "arbitrary precision computation". Basically concatenate multiple memory locations together to store one large number.

2. Once you get your program working then you can consider optimising it if, and only if, it does not perform to the required specification or, perhaps also if you just want some optimising experience for the sake of it.

3. Base conversion is really just a matter of repeatedly dividing by your base and saving the remainders, for display use the reverse order, or for storage directly in little endian format.
Post 16 Aug 2009, 09:56
View user's profile Send private message Visit poster's website Reply with quote
pal



Joined: 26 Aug 2008
Posts: 227
pal
Yeah, for number 1 that was what I was going to do.

The only problem is that I don't know how many bytes (or dwords as I have been working with before) something will take up. I was thinking for example something like this:

First parameter is a pointer to a memory address. The second parameter is the number of bytes in the memory address that contain relevant data. Loop through this data doing the different operations. Output to a third parameter which contains a pointer to a memory location for output. The only problem is, how do I know, with some functions, how many bytes I will need? E.g. Should I just take a log10 of the data (e.g. for 54321 * 12345 do a log(54321 * 12345)) and then round up, so in that example it would be 8.8 = 9 digits, and allocate an appropriate amount of memory?
Post 16 Aug 2009, 13:25
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
This article may be of some help to you: http://x86asm.net/articles/working-with-big-numbers-using-x86-instructions/index.html

Quote:
The only problem is, how do I know, with some functions, how many bytes I will need?

You can just estimate needed size in the beginning, and grow block of it needs to be larger (and optionally reallocate it to exact size when resulting size is known, if you are really concerned about memory and not so much about speed).

But it is also common to just pick "large enough" fixed size and use that.
Post 16 Aug 2009, 13:46
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1287
Location: behind the arc
Picnic
pal wrote:

3. Any links or pointers on how to do some of the other ones e.g. decimal to hexadecimal and decimal to any base.


This article also may be of some help, it shows a simple base conversion algorithm for arbitary size positive integers in any base 2-36.
Check the comments for correct output length computation.
I run some thousand digits conversion tests using googol+ to verify results.

http://www.codeproject.com/KB/recipes/BaseConverter.aspx
Post 30 Sep 2009, 15:38
View user's profile Send private message Reply with quote
pal



Joined: 26 Aug 2008
Posts: 227
pal
Picnic: Thanks, thats a nice find (the link). And also I didn't know about that Googol+ program, it looks very good. How does it compare to GP/PARI (if you have ever used it)?
Post 01 Oct 2009, 16:51
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1287
Location: behind the arc
Picnic
You're welcome pal. No i have neved used PARI/GP, searching about big numbers base conversion utility some time ago i discovered Googol+. Unfortunately it's not free.
Post 03 Oct 2009, 13:57
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


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