Prev: OctaOS
Next: DIV overflow
From: /o//annabee on 27 Mar 2007 01:51 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 27 Mar 2007 02:07 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 27 Mar 2007 04:28 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 27 Mar 2007 05:56 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 27 Mar 2007 06:44
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. |