⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arrays.hhf

📁 High Level assembly language(HLA)软件
💻 HHF
📖 第 1 页 / 共 5 页
字号:
					// Begin by checking to see if the highest dimension					// is _xpos_.  If so, use loop counter zero as the					// index value.  If not, use loop counter n (n=arity-1)					// as the index value.					?_i_ := @arity( _destArray_ ) - 1;					#if( _i_ = _xpos_ )						mov( (type dword [esp] ), edi );						#else						mov						( 							(type dword [esp + _i_*4] ), 							edi						);					#endif					// Okay, for all dimensions except _xpos_ and zero,					// compute the row-major offset into the array.					// Swap indicies zero and _xpos_.  Note that _xpos_					// may have been handled above.					?_i_ := _i_ - 1;					#while( _i_ > 0 )						array.mulbyConst						( 							@dim( _destArray_ )[_i_], 							edi 						);						#if( _i_ = _xpos_ )							add( [esp], edi );						#else							add( [esp+_i_*4], edi );						#endif						?_i_ := _i_ - 1;					#endwhile					array.mulbyConst( _dstd_[_xpos_], edi );					add( [esp + _xpos_*4], edi );					// Okay, EDI is the index into the destination array.					// ESI contains the pointer at the current source					// element.  Copy the data from the source array to					// the destination array.					#if( _dSize_ = 1 )						mov( [esi], al );						mov( al, [ebx+edi] );						inc( esi );					#elseif( _dSize_ = 2 )						mov( [esi], ax );						mov( ax, [ebx+edi*2] );						add( 2, esi );					#elseif( _dSize_ = 4 )						mov( [esi], eax );						mov( eax, [ebx+edi*4] );						add( 4, esi );					#else						mov( [esi], eax );						mov( [esi+4], edx );						mov( eax, [ebx+edi*8] );						mov( edx, [ebx+edi*8+4] );						add( 8, esi );					#endif					?_i_ := 0;					#while( _i_ < @arity( _destArray_ ))						endfor;						?_i_ := _i_ + 1;					#endwhile					// Remove loop control variables from the stack.										add( @arity( _destArray_ ) * 4, esp );					// Remove registers from the stack:					pop( edi );					pop( esi );					pop( ebx );					pop( eax );				#endif							#endif																		#else // Both arrays must be static.			?_srcd_ := @dim( _srcArray_ );			?_dstd_ := @dim( _destArray_ );			?_sSize_ := @ElementSize( _srcArray_ );			?_dSize_ := @ElementSize( _destArray_ );			#if			(					_sSize_ <> 1				&	_sSize_ <> 2				&	_sSize_ <> 4				&	_sSize_ <> 8				&	_sSize_ <> _dSize_			)				#error				(					"array.transpose: " nl					"Can only handle arrays with 1, 2, 4, or 8 byte elements"				);			#elseif			( 					@arity( _srcArray_ ) <= _xpos_ 				|	@arity( _destArray_ ) <= _xpos_				|	@arity( _srcArray_ ) <> @arity( _destArray_ ) 			)				#error				(					"array.transpose:" nl					"Arrays must have at least "					+ string( _xpos_ ) + " dimensions" nl					"and they must have the same number of dimensions"				);			#else				// Verify that the shapes of the arrays are reasonable.				#if				( 						_srcd_[0] <> _dstd_[_xpos_]					|	_srcd_[_xpos_] <> _dstd_[0]				)					#error					(						"array.transpose:" nl						"Array shapes are incorrect"					);				#else					?_i_ := 1;					#while( _i_ < @arity( _destArray_ ))						#if( _i_ <> _xpos_ )							#if( _srcd_[_i_] <> _dstd_[_i_] )								#error								(									"array.transpose:" nl									"Array shapes are incompatible"								)							#endif						#endif						?_i_ := _i_ + 1;					#endwhile				#endif				// Optimize the most common case (transposing				// a two-dim array or the last two dimensions				// of an array).				#if( _xpos_ = 1 )					push( eax );					push( ebx );					push( ecx );					push( edx );					push( esi );					push( edi );					lea( ebx, _srcArray_ );					lea( ecx, [ebx + @size( _srcArray_ )] );					push( ecx );					lea( ecx, _destArray_ );					sub( _dstd_[0] * _dstd_[1] * _dSize_, ecx );					while( ebx < [esp] ) do						add( _dstd_[0] * _dstd_[1] * _dSize_, ecx );						for( mov(0, esi ); esi < _dstd_[0]; inc( esi )) do							for							(								mov( 0, edi ); 								edi < _dstd_[_xpos_]; 								inc( edi )							) do								#if( _sSize_ = 1 )									intmul( _dstd_[0], edi, edx );									add( esi, edx );									mov( [ebx], al );									mov( al, [ecx+edx] );									inc( ebx );								#elseif( _sSize_ = 2 )									intmul( _dstd_[0], edi, edx );									add( esi, edx );									mov( [ebx], ax );									mov( ax, [ecx+edx*2] );									add( 2, ebx );								#elseif( _sSize_ = 4 )									intmul( _dstd_[0], edi, edx );									add( esi, edx );									mov( [ebx], eax );									mov( eax, [ecx+edx*4] );									add( 4, ebx );								#elseif( _sSize) = 8 )									intmul( _dstd_[0], edi, edx );									add( esi, edx );									mov( [ebx], eax );									mov( eax, [ecx+edx*8] );									mov( [ebx+4], eax );									mov( eax, [ecx+edx*8+4] );									add( 8, ebx );								#endif							endfor;						endfor;					endwhile;					add( 4, esp );					pop( edi );					pop( esi );					pop( edx );					pop( ecx );					pop( ebx );					pop( eax );								// Okay, handle the case where we are not transposing				// the last two dimensions of the array.  This one is				// ugly and less efficient (hence the special case				// above).				#else					// Make room for a set of loop control variables					// on the stack:					push( eax );					push( ebx );					push( esi );					push( edi );					lea( esi, _srcArray_ );					lea( ebx, _destArray_ );					sub( @arity( _destArray_ ) * 4, esp );					?_i_ := @arity( _destArray_ );					#while( _i_ > 0 )						?_offset_ := ( _i_ - 1 ) * 4;						for						( 							mov(0, (type dword [esp+_offset_]));							(type dword [esp+_offset_]) < _dstd_[_i_ - 1];							inc( (type dword [esp+_offset_]))						) do						?_i_ := _i_ - 1;					#endwhile					// Compute index into the destination array.					// Note: to properly transpose, we need to					// swap the zero index with the _xpos_ index.					//					// Begin by checking to see if the highest dimension					// is _xpos_.  If so, use loop counter zero as the					// index value.  If not, use loop counter n (n=arity-1)					// as the index value.					?_i_ := @arity( _destArray_ ) - 1;					#if( _i_ = _xpos_ )						mov( (type dword [esp] ), edi );						#else						mov						( 							(type dword [esp + _i_*4] ), 							edi						);					#endif					// Okay, for all dimensions except _xpos_ and zero,					// compute the row-major offset into the array.					// Swap indicies zero and _xpos_.  Note that _xpos_					// may have been handled above.					?_i_ := _i_ - 1;					#while( _i_ > 0 )						array.mulbyConst						( 							_dstd_[_i_], 							edi 						);						#if( _i_ = _xpos_ )							add( [esp], edi );						#else							add( [esp+_i_*4], edi );						#endif						?_i_ := _i_ - 1;					#endwhile					array.mulbyConst( _dstd_[_xpos_], edi );					add( [esp + _xpos_*4], edi );					// Okay, EDI is the index into the destination array.					// ESI contains the pointer at the current source					// element.  Copy the data from the source array to					// the destination array.					#if( _dSize_ = 1 )						mov( [esi], al );						mov( al, [ebx+edi] );						inc( esi );					#elseif( _dSize_ = 2 )						mov( [esi], ax );						mov( ax, [ebx+edi*2] );						add( 2, esi );					#elseif( _dSize_ = 4 )						mov( [esi], eax );						mov( eax, [ebx+edi*4] );						add( 4, esi );					#else						mov( [esi], eax );						mov( [esi+4], edx );						mov( eax, [ebx+edi*8] );						mov( edx, [ebx+edi*8+4] );						add( 8, esi );					#endif					?_i_ := 0;					#while( _i_ < @arity( _destArray_ ))						endfor;						?_i_ := _i_ + 1;					#endwhile					// Remove loop control variables from the stack.										add( @arity( _destArray_ ) * 4, esp );					// Remove registers from the stack:					pop( edi );					pop( esi );					pop( ebx );					pop( eax );				#endif							#endif		#endif	#endmacro/*************************************************************************/////	print( array, minwidth, decpts )	#macro print( _arrayToPrint_, _fmt_[] ):		_dims_,		_Arity_,		_fmtOptions_,		_elementTypeName_;		#if( @elements( _fmt_ ) = 0 )			?_fmtOptions_:text := "";		#elseif( @elements( _fmt_ ) = 1 )			?_fmtOptions_:text := ":" + _fmt_[0];		#elseif( @elements( _fmt_ ) = 2 )			?_fmtOptions_:text := ":" + _fmt_[0] + ":" + _fmt_[1];		#else			#error( "array.print: too many parameters" );			?_fmtOptions_:text := "";		#endif		push( eax );		push( edx );		push( esi );		push( edi );		#if( !array.isItDynamic( _arrayToPrint_ ))			?_dims_ := @dim( _arrayToPrint_ );			?_Arity_ := @arity( _arrayToPrint_ );			xor( esi, esi );			mov( 1, edi );			while( edi <= @elements( _arrayToPrint_ ) ) do				stdout.put( _arrayToPrint_[ esi ] _fmtOptions_ );				#if( _Arity_ > 1 )									mov( edi, eax );					cdq();					div( _dims_[ 0 ], edx:eax );					if( !edx ) then						stdout.newln();						#if( _Arity_ > 2 )							mov( edi, eax );							cdq();							div( _dims_[0] * _dims_[1], edx:eax );							if( !edx ) then								stdout.newln();							endif;						#endif					else						stdout.put( ", " );					endif;				#endif				add( @ElementSize( _arrayToPrint_ ), esi );				inc( edi );			endwhile;		#else			?_Arity_ := 1;			push( ecx );			push( ebx );			mov( _arrayToPrint_.dopeVector[0], ecx );			mov( _arrayToPrint_.dataPtr, esi );			#while( _Arity_ < @elements( _arrayToPrint_.dopeVector ) )				intmul( _arrayToPrint_.dopeVector[ _Arity_*4 ], ecx );				?_Arity_ := _Arity_ + 1;			#endwhile			mov( _arrayToPrint_.dataPtr, esi );			mov( 1, edi );			while( edi <= ecx ) do				?_elementTypeName_:text := @typename( _arrayToPrint_.elementType );				stdout.put				( 					(type  _elementTypeName_ [ esi ]) 					_fmtOptions_ 				);				#if( @elements( _arrayToPrint_.dopeVector ) > 1 )									mov( edi, eax );					cdq();					div					( 						(type uns32 _arrayToPrint_.dopeVector[0]), 						edx:eax 					);					if( !edx ) then						stdout.newln();						#if( _Arity_ > 2 )							mov( _arrayToPrint_.dopeVector[ 0 ], ebx );							intmul(	_arrayToPrint_.dopeVector[ 4 ], ebx );							mov( edi, eax );							cdq();							div( ebx, edx:eax );							if( !edx ) then								stdout.newln();							endif;						#endif					else						stdout.put( ", " );					endif;				#endif				add( @Size( _arrayToPrint_.elementType ), esi );				inc( edi );			endwhile;			pop( ebx );			pop( ecx );						#endif		pop( edi );		pop( esi );		pop( edx );		pop( eax );		// Deallocate compile-time storage for _dims_		?_dims_ := 0;	#endmacro/*************************************************************************///// lookupTable-//// Generate a lookup table (only in the read-only data section)//// Usage:////  someID: //		array.lookupTable//		( //			elementType,//			defaultCaseLabel, //			tableValue:indexList, //			tableValue:indexList, //			... //		);//// For each value in the indexList list of values, this macro inserts// the "tableValue" into the array at each specified index, e.g.,////    luTable : //        array.lookupTable//        (//			dword,			// Data type//            $ff,			// Default value for empty holes.//            10: 9, //            11: 10, //            12: 0, //            13: 5, //            14: 12, //            15: 8, //            16: 16, //            18: 14 15, //            19: 6 7 11 13, //            20: 1 //        );//// This creates the following array:////	luTable:dword[17] :=//		[//			12,			// from 12:0//			20,			// from 20:1//			$ff,//			$ff,//			$ff,//			13,			// from 13:5//			19,			// from 19:6 7 11 13//			19,			//  "    "   "   "//			15,			// from 15:8//			10,			// from 10:9//			11,			// from 11:10//			19,			// from 19:6 7 11 13//			14,			// from 14:12//			19,			// from 19:6 7 11 13//			18,			// from 18:14 15//			18,			// from 18:14 15//			16			// from 16:16//	];//// This macro serves as a "data type" declaration returning the type and// constant data for a lookup table. It also defines the following constants:////	someID_minValue - Minimum lookup value appearing in the table.//	someID_minIndex - Minimum lookup value times the size of a table entry.////	someID_maxValue - Maximum lookup value appearing in the table.//	someID_maxIndex - Maximum lookup value times the size of a table entry.// Constants you may want to change to control warnings emitted by// the mwjmp macro:val    maxCases    := 4096;    // Maximum # of cases we will allow                                largeTable  := 256;     // A "large" table has at least 256 entries        sparseTable := 4;       // A "sparse" table is one that has 4x as                            // many (or more) unused entries as it has                            // actual entries.type    caseRecord:        record            value   :dword;            lblStr  :string;        endrecord;        val    cases   	:caseRecord[ maxCases ] := maxCases dup [caseRecord:[0,""]];		leftItem	:caseRecord := caseRecord:[ 0, "" ];	rightItem	:caseRecord := caseRecord:[ 0, "" ];			#macro lessThan;			(array.leftItem.value < array.rightItem.value)			#endmacro                    	#macro lookupTable( tableType, _defaultCase_, _entries_[] ):	    _boundsError_,	    _numEntries_, 	    _i_,	    _j_,	    _k_,		_m_,	    _endLabel_,	    _tableValue_,	    _valueList_,	    _slots_,	    _minLabel_,		_maxLabel_,	    _tableID_;	    // First, save the label applied to this array so we	    // can generate the minLabel later.	    	    forward( _tableID_ );   	    ?_numEntries_ := @elements( _entries_ );	    	    // Okay, parse each of the arguments and extract the constant	    // and label c

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -