Prev: OctaOS
Next: DIV overflow
From: /o//annabee on
P� Tue, 27 Mar 2007 07:17:53 +0200, skrev rhyde(a)cs.ucr.edu
<rhyde(a)cs.ucr.edu>:


>>
>> stdlib.hexConvTbl ?
>
> Sorry,

:) Counted. Now you only have 9855 sorries to go.

> Cheers,
> Randy Hyde
From: Guga on
On Mar 26, 9:17 pm, "r...(a)cs.ucr.edu" <r...(a)cs.ucr.edu> wrote:
> On Mar 26, 9:06 pm, "Guga" <Guga...(a)gmail.com> wrote:
>
>
>
>
>
> > On Mar 26, 8:54 pm, "r...(a)cs.ucr.edu" <r...(a)cs.ucr.edu> wrote:
>
> > > On Mar 26, 11:39 am, "Guga" <Guga...(a)gmail.com> wrote:
>
> > > > Hi guys
>
> > > > someone knows how to convert an null terminated ascii string to
> > > > tword ? (80 bits)
>
> > > > I suceeded to convert an ascii to qword, making an similar function as
> > > > atoi64, but i can´t extend the convertion to 80 bits.
>
> > > > Some one knows how to convert? Also for 128 bit would be good too :)
>
> > > > Btw: If someone have a C source of those routines and not an assembly
> > > > one.. no problem...i can try translate to assembly;
>
> > > > Best Regards,
>
> > > > Guga
>
> > > // I, Randall Hyde, hereby agree to waive all claim of copyright
> > > (economic
> > > // and moral) in all content contributed by me, the user, and
> > > immediately
> > > // place any and all contributions by me into the public domain; I
> > > grant
> > > // anyone the right to use my work for any purpose, without any
> > > // conditions, to be changed or destroyed in any manner whatsoever
> > > // without any attribution or notice to the creator. I also absolve
> > > myself
> > > // of any responsibility for the use of this code, the user assumes
> > > all
> > > // responsibilities for using this software in an appropriate manner.
> > > //
> > > // Notice of declaration of public domain, 7/12/2006, by Randall Hyde
>
> > > unit ConvUnit;
>
> > > #include( "../include/conversions.hhf" )
> > > #include( "stdlibdata.hhf" )
>
> > > /**************************************************************/
> > > /* */
> > > /* atoh80- */
> > > /* */
> > > /* ESI points at a sequence of characters that represent */
> > > /* a hexadecimal value. This function converts that sequence */
> > > /* to the numeric equivalent and returns the result in */
> > > /* tb. ESI is left pointing at the first non-hex */
> > > /* character. See atou and atoi for more details on this */
> > > /* routine. */
> > > /* */
> > > /**************************************************************/
>
> > > procedure conv.atoh80( var buffer:var in esi; var tb:tbyte );
> > > @nodisplay;
> > > @noframe;
>
> > > var
> > > edxSave :dword;
> > > ecxSave :dword;
> > > ebxSave :dword;
> > > eaxSave :dword;
>
> > > begin atoh80;
>
> > > push( ebp );
> > > mov( esp, ebp );
> > > sub( _vars_, esp );
> > > mov( eax, eaxSave );
> > > mov( ebx, ebxSave );
> > > mov( ecx, ecxSave );
> > > mov( edx, edxSave );
>
> > > xor( eax, eax ); // Init H.O. three bytes of EAX to zero.
> > > mov( eax, edx ); // Initialize EDX:ECX with zero.
> > > mov( eax, ecx );
>
> > > // Skip over any delimiter characters at the beginning
> > > // of the string.
>
> > > sub( 1, esi );
> > > whileDelimLoop:
>
> > > NextChar;
> > > cmp( eax, $80 );
> > > jae IllegalChar;
> > > bt( eax, Delimiters );
> > > jc whileDelimLoop;
>
> > > // Do the actual numeric conversion:
>
> > > xor( eax, eax ); // Init H.O. three bytes of EAX to zero.
> > > mov( eax, ebx ); // Initialize EDX:ECX:EBX with zero.
> > > mov( eax, ecx );
> > > mov( eax, edx );
>
> > > // Skip over any delimiter characters at the beginning
> > > // of the string.
>
> > > sub( 1, esi );
> > > whileDelimLoop_2:
>
> > > NextChar;
> > > cmp( eax, $80 );
> > > jae IllegalChar;
> > > bt( eax, (type dword Delimiters ));
> > > jc whileDelimLoop_2;
>
> > > // The first (non-delimiter) character *must* be a legal hex
> > > digit.
>
> > > movzx( (type byte [esi]), eax );
> > > movsx( stdlib.hexConvTbl[eax], eax );
> > > test( eax, eax );
> > > js convError;
>
> > > // For each legal character that ESI points at, repeat
> > > // the following until we encounter a delimiter or
> > > // illegal character.
>
> > > whileAHexDigit:
>
> > > // Okay, we've got a hex digit, so add it into EDX:ECX.
>
> > > cmp( edx, $1000 );
> > > jae Overflow;
> > > shl( 28, eax );
> > > shld( 4, ecx, edx );
> > > shld( 4, ebx, ecx );
> > > shld( 4, eax, ebx );
>
> > > // Move on to the next character:
>
> > > NextChar;
> > > movsx( stdlib.hexConvTbl[eax], eax ); // $ff if not a hex
> > > digit
> > > test( eax, eax );
> > > jns whileAHexDigit;
>
> > > // Verify that we've ended with a delimiter char:
>
> > > movzx( (type byte [esi]), eax );
> > > bt( eax, Delimiters );
> > > jnc convError;
>
> > > // Store away the result:
>
> > > mov( tb, eax );
> > > mov( ebx, [eax] );
> > > mov( ecx, [eax+4] );
> > > mov( dx, [eax+8] );
>
> > > mov( eaxSave, eax );
> > > mov( ebxSave, ebx );
> > > mov( ecxSave, ecx );
> > > mov( edxSave, edx );
> > > leave();
> > > ret( _parms_ );
>
> > > convError:
> > > raise( ex.ConversionError );
>
> > > Overflow:
> > > raise( ex.ValueOutOfRange );
>
> > > IllegalChar:
> > > raise( ex.IllegalChar );
>
> > > end atoh80;
>
> > > end ConvUnit;
>
> > > Cheers,
> > > Randy Hyde- Hide quoted text -
>
> > > - Show quoted text -
>
> > Tks, Randall...
>
> > I´m reading and trying to follow the code.
>
> > The order of the registers are swaped, right ?
>
> > and...what is
>
> > stdlib.hexConvTbl ?
>
> Sorry,
>
> namespace stdlib;
>
> readonly(16)
>
> // HexConvTable-
> // The eight-bit index into this table returns the numeric
> equivalent
> // of a hexadecimal character (0..$F) . If the index character
> value
> // is not a valid hex char, then the table entry contains $FF.
>
> hexConvTbl: byte[256] :=
> [
> #for( i := 0 to (@uns8( '0' ) - 1) )
>
> $ff,
>
> #endfor
>
> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
>
> #for( i := (@uns8( '9' )+1) to (@uns8( 'A' )-1 ))
>
> $ff,
>
> #endfor
>
> $a, $b, $c, $d, $e, $f,
>
> #for( i := @uns8( 'G' ) to (@uns8( 'a' )-1 ))
>
> $ff,
>
> #endfor
>
> $a, $b, $c, $d, $e, $f,
>
> #for( i := @uns8( 'g' ) to $fe )
>
> $ff,
>
> #endfor
> $ff
> ];
>
> end stdlib;
>
> This is a 256-byte table that contains $FF everywhere except in the
> character positions '0'..'9', 'A'..'F', and 'a'..'f', where it places
> the numeric values for these characters.
>
> While I'm at it, I should point out that "delimiters" is a bit array
> defined in HLA as follows:
>
> static
>
> Delimiters: cset :=
> {
> #0, #9, #10, #13,
> ' ',
> ',',
> ';',
> ':'
> };
>
> This is an array of 16 bytes (128 bits) that has '1' bits in bit
> positions corresponding to each of the character values, i.e.,
>
> CONV_DELIMITERS label byte
> byte 01h,026h,00h,00h,01h,010h,00h,0ch,00h,00h,00h,
> 00h,00h,00
> h,00h,00h
>
> Cheers,
> Randy Hyde- Hide quoted text -
>
> - Show quoted text -


I didn´t undertstood what you did with shld.

I made this:

mov esi D(a)String <--- pointer to a string "18446744073709551615",
0. Sure.. this is not a 80 bit.. but it should show me this values in
hexadecimal format: 0FFFFFFFF 0FFFFFFFF.. bt.. it is not.. it is
resulting:
eax = 0FFFF FFD0
ebx = 0955 1615
ecx = 6744 0737
edx = 0000 1844

when it should result:
eax = 0FFFF FFFF
ebx = 0FFFF FFFF
ecx = 0000 0000
edx = 0000 0000

and.. of course... if i entered the decimal string in the proper size,
such as: "1699504104824251512520704", 0 it should result the proper
values in eax, ebx, ecx and edx.. but....it is not working.

I can´t understand the logic of using shld

here is the code:


xor ecx ecx
xor eax eax
xor ecx ecx
xor ebx ebx
xor edx edx

movsx eax B$esi
sub eax '0'

While B$esi <> 0 ; when we reach the end of the string we ends the
loop

shl eax 28
shld edx ecx 4
shld ecx ebx 4
shld ebx eax 4

inc esi
movsx eax B$esi
sub eax '0'
End_While


Best Regards,

Guga

From: Frank Kotler on
Guga wrote:

....
> I can�t understand the logic of using shld

Randy is doing *hex* ascii to integer. The "shld 4" does a multi-dword
multiply by *16*.

I *completely* misunderstood what you were trying to do. The code from
Nasm64developer is to convert a "float string" (can contain '.', 'e',
etc. plus decimal digits) to IEEE???(whatever that number is... 754)
floating-point format. Still an "interesting" project, perhaps, but not
what you want, at all!

With my New Improved (mis)Understanding, this looks a lot easier. I'm
not sure what you'd do with a tbyte/tword integer, but if you can
multiply a tword by ten, you've got it made. Might be worth developing
an "arbitrary size" multiply, rather than specifically tword. Lemme
think on this a little...

Best,
Frank
From: Herbert Kleebauer on
Frank Kotler wrote:>
> Guga wrote:
>
> ...
> > I can�t understand the logic of using shld
>
> Randy is doing *hex* ascii to integer. The "shld 4" does a multi-dword
> multiply by *16*.
>
> I *completely* misunderstood what you were trying to do. The code from
> Nasm64developer is to convert a "float string" (can contain '.', 'e',
> etc. plus decimal digits) to IEEE???(whatever that number is... 754)
> floating-point format. Still an "interesting" project, perhaps, but not
> what you want, at all!
>
> With my New Improved (mis)Understanding, this looks a lot easier. I'm
> not sure what you'd do with a tbyte/tword integer, but if you can
> multiply a tword by ten, you've got it made. Might be worth developing
> an "arbitrary size" multiply, rather than specifically tword. Lemme
> think on this a little...

I also supposed he wants to convert floating point numbers. Here
a decimal ascii to binary conversion for multi precision integers
(one with and one without "mult" instruction, don't now which
one is faster):


@=$100
size=16 ; size in 32 bit words

move.l #dec_ascii,r3
bsr.l atoi1 ; convert with div
bsr.l dec_dump

move.l #dec_ascii,r3
bsr.l atoi2 ; concert with shift+add
bsr.l dec_dump

rts.w

atoi1: move.l #result,r6
move.l #size,r2
eor.l r0,r0
rep_r2 move.l r0,(r6)+-{s1}

move.l #10,r6
_20: movu.bl (r3),r2
inc.l r3
cmp.b #'9',r2
bhi.l _done
sub.b #'0',r2
bcs.l _done

move.l #result,r5
eor.l r4,r4
_10: move.l (r5,r4*4),r0
mulu.l r6,r0,r1|r0
add.l r2,r0
move.l r0,(r5,r4*4)
move.l r1,r2
inc.l r4
cmp.l #size-1,r4
bls.b _10
br.b _20
_done: rts.l

atoi2: move.l #result,r6
move.l #size,r2
eor.l r0,r0
rep_r2 move.l r0,(r6)+-{s1}

_20: movu.bl (r3),r1
inc.l r3
cmp.b #'9',r1
bhi.l _done
sub.b #'0',r1
bcs.l _done

move.l #result,r5
move.l #size-2,r4
_30: move.l (r5,r4*4),r0
dsl.l #1,4.b(r5,r4*4)<r0
dec.l r4
bpl.b _30
lsl.l #1,(r5)

move.l #tmp,r6
move.l #size,r2
rep_r2 move.l (r5)+-,(r6)+-{s1}

move.l #result,r5
move.l #size-2,r4
_40: move.l (r5,r4*4),r0
dsl.l #2,4.b(r5,r4*4)<r0
dec.l r4
bpl.b _40
lsl.l #2,(r5)

eor.l r4,r4
move.l #size,r2
move.l #tmp,r6

cmp.b #7,r1
bls.b _50
addq.l #7,(r5)
addq.l #1,(r6)
add.b #256-9,r1
br.b _10
_50: add.l r1,(r5)

_10: move.l (r6,r4*4),r0
addc.l r0,(r5,r4*4)
inc.l r4
dbf.l r2,_10
br.l _20
_done: rts.l


dec_ascii: dc.b "1234567890123456789011223344556677889900111222333444555",0


dec_dump:
move.l #10,r3
move.l #text_out_end,r6

_20: move.l #result,r5
move.l #size-1,r4
eor.l r1,r1
eor.l r2,r2
_10: move.l (r5,r4*4),r0
divu.l r3,r1|r0
move.l r0,(r5,r4*4)
or.l r0,r2
dec.l r4
bpl.b _10
add.b #'0',r1
dec.l r6
move.b r1,(r6)
tst.l r2,r2
bne.b _20

subq.l #4,r6
move.l #$0a0d0a0d,(r6)
move.b #$40,m0
move.w r6,r1
move.l #text_out_end,r2
sub.w r1,r2
move.w #1,r3
trap #$21

rts.l


even 4
result: blk.l size
tmp: blk.l size

text_out: blk.b size*10+10
text_out_end:
From: Herbert Kleebauer on
Herbert Kleebauer wrote:
>
> I also supposed he wants to convert floating point numbers. Here
> a decimal ascii to binary conversion for multi precision integers
> (one with and one without "mult" instruction, don't now which
> one is faster):

Sorry, the version with "mul" isn't correct. I let it as an exercise
for the "dear reader" to insert the one missing instruction.
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13
Prev: OctaOS
Next: DIV overflow