Prev: OctaOS
Next: DIV overflow
From: Wolfgang Kern on

Hi Guga,

? 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
> atoi64, but i can�t extend the convertion to 80 bits.

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

DON'T use the awful slow FBSTP with the associeted story.

Have ou seen the RosAsm examples for 'primes SSE' on my page ?
Might be easy expandable to 128-bit even this code is not optimized.

__
wolfgang



From: rhyde on
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

From: Guga on
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 ?


Best Regards,.

Guga

From: Guga on
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 ?
>
> Best Regards,.
>
> Guga- Hide quoted text -
>
> - Show quoted text -


My main problem is that i can´t get the logics behind a convertion to
80 or 128bit.

and.. why shld and not a mul ?

Wouldn´t shld be slower ?

Best Regards,

Guga

From: rhyde on
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


First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10 11 12
Prev: OctaOS
Next: DIV overflow