Console ASCII interpretation
alexander
arundel at h3c.de
Mon May 16 20:56:56 GMT 2005
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 at 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
*****************************************************************************
More information about the freebsd-hackers
mailing list