Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 May 2005 22:56:47 +0200
From:      alexander <arundel@h3c.de>
To:        freebsd-hackers@freebsd.org
Subject:   Re: Console ASCII interpretation
Message-ID:  <20050516205647.GA21498@skatecity>
In-Reply-To: <200505162032.j4GKWFqe072034@realtime.exit.com>
References:  <20050516202029.GA21139@skatecity> <200505162032.j4GKWFqe072034@realtime.exit.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon May 16 05, Frank Mayhar wrote:
> 
> Not "much easier."  "Correct."
> 
> The fact that your code wrote three NULs to the console in the first
> place meant that your code, not the console, was broken.
> -- 
> Frank Mayhar frank@exit.com	http://www.exit.com/
> Exit Consulting                 http://www.gpsclock.com/
>                                 http://www.exit.com/blog/frank/

OK. Got it. I was just a bit surprised, because the code I'm using is taken
from a site called 'The assembly gems page'. The author claims that he tested
this code very throroughly.

It seems not thoroughly enough.

Thx for all the help.

*****************************************************************************

Here's the code if anybody is interested. %eax=ulong, %edi=mem_pointer

ulong2ascii:			; Credits go to Norbert Juffa and
				; John Eckerdal's 'Assembly Gems page'
                		; at http://www.df.lth.se/~john_e/

        mov     ecx,eax         ; save original argument
        mov     esi,89705f41h   ; 1e-9*2^61 rounded
        mul     esi             ; divide by 1e9 by mult. with recip.
        add     eax,80000000h   ; round division result
        mov     esi,0abcc7712h  ; 2^28/1e8 * 2^30 rounded up
        adc     edx,0           ; EDX<31:29> = argument / 1e9
        mov     eax,ecx         ; restore original argument
        shr     edx,29          ; leading decimal digit, 0...4
        mov     ecx,8           ; produce eight more digits
        mov     ebx,edx         ; flags whether non-zero digit seen yet
        or      edx,'0'         ; convert digit to ASCII
        mov     [edi],dl        ; store out to memory
        cmp     ebx,1           ; first digit nonzero ? CY=0 : CY=1
        sbb     edi,-1          ; incr. pointer if first digit non-zero

        imul    ebx,1000000000  ; multiply quotient digit by divisor
        sub     eax,ebx         ; remainder after first digit

        mul     esi             ;  convert number < 1e9
        shld    edx,eax, 2      ;   into fraction such
        inc     edx             ;    that 1.0 = 2^28
        mov     eax,edx         ; save result
        shr     eax,28          ; next digit
        and     edx,0fffffffh   ; fraction part
        or      ebx,eax         ; any non-zero yet ?
        or      eax,'0'         ; convert digit to ASCII
cvt_loop:
        mov     [edi],al        ; store digit out to memory
        add     edx,edx         ; 2*fraction
        cmp     ebx,1           ; any non-zero digit seen ? CY=0 : CY=1
        lea     edx,[edx*4+edx] ; 10*fraction, new digit EAX<31:28>,
                                ; new fraction EAX<27:0>
        sbb     edi,-1          ; incr. ptr if any non-zero digit seen
        mov     eax,edx         ; save result
        shr     eax,28          ; next digit = integer part
        and     edx,0fffffffh   ; fraction part
        or      ebx,eax         ; any non-zero digit yet ?
        or      eax,'0'         ; convert digit to ASCII
        dec     ecx             ; one more digit
        jnz     cvt_loop        ; until all nine digits done
        mov     [edi],al        ; store last digit out to memory
        mov     [edi+1],ah      ; place string end marker

        ret

*****************************************************************************



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050516205647.GA21498>