Prev: OctaOS
Next: DIV overflow
From: Wolfgang Kern on 26 Mar 2007 20:54 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 27 Mar 2007 00:54 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 27 Mar 2007 01:06 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 27 Mar 2007 01:12 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 27 Mar 2007 01:17
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 |