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

📄 stl.hhf

📁 High Level assembly language(HLA)软件
💻 HHF
📖 第 1 页 / 共 5 页
字号:
////////////////////////////////////////////////////////////////////////////////// Container-//// All container objects are a subclass of "Container"type	Container:		class inherits( base );			val				hierarchy_c := hierarchy_c | isContainer_c;			var				align(4);				// # of elements (nodes, whatever) in the container				numElements	:uns32;				// For containers (i.e., the isContainer_c bit is set in				// capabilities), containerName specifies the name of				// the container (e.g., "vector")				containerName		:string;			method getSize; @returns( "eax" );		endclass;		// getSize-		//	Returns the number of container items in EAX:		method Container.getSize; @noframe;		begin getSize;			mov( this.numElements, eax );			ret();		end getSize;static	vmt(Container);//////////////////////////////////////////////////////////////////////////////// RandomAccessContainer-// 	All Random Access class objects are a subclass of RandomAccessContainer:type	RandomAccessContainer:		class inherits( Container );			val				hierarchy_c := hierarchy_c | isRandomAccess_c;		endclass;//////////////////////////////////////////////////////////////////////////////// ArrayContainer-// 	All Array class objects are a subclass of ArrayContainer:type	ArrayContainer:		class inherits( RandomAccessContainer );			val				hierarchy_c := hierarchy_c | isArray_c;			var				align( 4 );				// Pointer to allocated storage:				allocData		:dword;				// Pointer to end of allocated storage				endAllocData	:dword;				// Max space for current allocation				allocSize		:uns32;				// Pointer to start of array data:				data			:dword;				// Pointer to end of array data:				endData			:dword;				// Size of array data currently in use				dataSize		:uns32;								method getAllocSize; @returns( "eax" );			method getDataSize;	@returns( "eax" );			method createArray( n:uns32; elementSize:uns32 );			method clear;			method destroy;		endclass;		method ArrayContainer.getAllocSize; @noframe;		begin getAllocSize;			mov( this.allocSize, eax );			ret();		end getAllocSize;		method ArrayContainer.getDataSize; @noframe;		begin getDataSize;			mov( this.dataSize, eax );			ret();		end getDataSize;		// Create a generic array object		// (this is a private routine for use by derivative classes)		method ArrayContainer.createArray( n:uns32; elementSize:uns32 );			@nodisplay; @nostackalign;		begin createArray;			push( eax );			// Allocate storage for the array and initialize			// the appropriate fields:			mov( 0, this.numElements );	// No actual elements in use yet.			mov( 0, this.dataSize );			mov( n, eax );			intmul( elementSize, eax );			mov( eax, this.allocSize );	// Allocated size for vector.			@global:mem.alloc( eax );			mov( eax, this.allocData );	// Pointer to allocated data.			mov( eax, this.data );			mov( eax, this.endData );	// Empty vector, endData is same as data			add( this.allocSize, eax );	// Compute endAllocData			mov( eax, this.endAllocData );			pop( eax );		end createArray;		// Destroy-		//	This is the generic destructor for array types.		method ArrayContainer.destroy; @noframe;		begin destroy;			@global:mem.free( this.allocData );	// Free the data storage			xor( eax, eax );			mov( eax, this.allocData );			mov( eax, this.endAllocData );			mov( eax, this.data );			mov( eax, this.endData );			mov( eax, this.allocSize );			mov( eax, this.numElements );			mov( eax, this.dataSize );			if( this.isAlloc ) then				// If object was created on the heap, free it here:				@global:mem.free( esi );			endif;			ret();		end destroy;		// Clear-		//	Clears (but does not deallocate storage) all the elements		//	in the array.		method ArrayContainer.clear; @noframe;		begin clear;			push( eax );			mov( 0, this.numElements );			mov( 0, this.dataSize );			mov( this.data, eax );			mov( eax, this.endData );			pop( eax );			ret();		end clear;	static		vmt( ArrayContainer );		////////////////////////////////////////////////////////////////////////////////// _vector//	This is a special "helper" class for the vector template that moves a lot//	of code common to all vector types into a single class in order to reduce//	the size of the code base produced by expanding a vector template. No//	program should actually declare variables of type _vector, this class is//	for internal use only.type	_vector:		class inherits( ArrayContainer );					procedure _append( toAppend:dword; appendSize:dword ); @use eax;			procedure _insert			( 				toInsert:dword; 				insertWhere:dword; 				insertSize:dword 			);			procedure _remove( removeWhere:dword; removeSize:dword );					endclass; 		// _append-		//	Appends a new element to the end of the vector.		//		// Inputs:		//		//	toAppend-		//		Pointer to the data to append to the vector		//		//	appendSize-		//		Size of the data object to append.		procedure _vector._append( toAppend:dword; appendSize:dword );			@nodisplay; @noalignstack;		readonly			sixteenCases:dword[17] :=				[					&defaultCase,					&case1,					&case2,					&defaultCase,					&case4,					&defaultCase,					&defaultCase,					&defaultCase,					&case8,					&defaultCase,					&defaultCase,					&defaultCase,					&defaultCase,					&defaultCase,					&defaultCase,					&defaultCase,					&case16				];		begin _append;			// Begin by making sure we've got enough room in the			// data array to hold the new object:			mov( this.dataSize, edi );			add( appendSize, edi );			if( edi >= this.allocSize ) then				// If the new element we're adding pushes us				// beyond the end of the allocated storage,				// reallocate by doubling the storage.				shl( 1, edi );				mov( edi, this.allocSize );				@global:mem.realloc( this.allocData, edi );				mov( eax, this.data );				mov( eax, this.allocData );				add( eax, edi );				mov( edi, this.endAllocData );			endif;			// Special case out various small object sizes			// for performance reasons.			mov( appendSize, ecx );			mov( this.data, edi );			add( this.dataSize, edi );			push( esi );			mov( toAppend, esi );			cld();			cmp( ecx, 16 );			ja defaultCase;			jmp( sixteenCases[ ecx*4 ]);			case1:				movsb();				jmp caseDone;			case2:				movsw();				jmp caseDone;			case4:				movsd();				jmp caseDone;			case8:				movsd();				movsd();				jmp caseDone;			case16:				movsd();				movsd();				movsd();				movsd();				jmp caseDone;			defaultCase:				rep.movsb();			caseDone:			pop( esi );			mov( edi, this.endData );	// Maintain ptr to end of data.			// Okay, bump up the element count by one:			add( 1, this.numElements );			mov( appendSize, eax );			add(eax, this.dataSize );		end _append;		// _insert-		//	Inserts an arbitrary "vector" object into a vector.		//		//	Inputs:		//		//	toInsert-		//		Pointer to vector element to insert into the list.		//		//	insertWhere-		//		Pointer to the spot in the vector where the new element		//		is to be inserted.		//		//	insertSize-		//		Size of the object being inserted.		procedure _vector._insert		( 			toInsert:dword; 			insertWhere:dword; 			insertSize:dword 		);		begin _insert;			push( esi );			// As we're expanding the array by one element, let's make			// sure we have room for the expansion:			mov( this.dataSize, ecx );			add( insertSize, ecx );			if( ecx >= this.allocSize ) then				// If the new element we're adding pushes us				// beyond the end of the allocated storage,				// reallocate by doubling the storage.				lea( ecx, [ecx+ecx] );				mov( ecx, this.allocSize );				@global:mem.realloc( this.allocData, ecx );				mov( eax, this.data );				mov( eax, this.allocData );				add( ecx, eax );				mov( eax, this.endAllocData );				sub( ecx, eax );				add( this.dataSize, eax );				mov( eax, this.endData );			endif;			// Okay, make room for the item we're going to insert:			mov( insertWhere, eax );			if( eax >= this.endData ) then				mov( this.endData, eax );			else				// If we are inserting data at some point other than				// at the end of the array, then we've got to move				// everything along by one position to open up space				// for the new element:				std();				mov( this.endData, edi );				mov( edi, ecx );				sub( eax, ecx );				// Three variants of the actual insertion code,				// based on the size of the object we're inserting:				test( %11, insertSize );				jz do4;				test( %1, insertSize );				jz do2;					lea( esi, [edi-1] );					add( insertSize, edi );					sub( 1, edi );					rep.movsb();					jmp SpaceMade;				do2:					// Do this if the object's size is a multiple of 2 bytes:					lea( esi, [edi-2] );					add( insertSize, edi );					sub( 2, edi );					shr( 1, ecx );					rep.movsw();					jmp SpaceMade;				do4:					lea( esi, [edi-4] );					add( insertSize, edi );					sub( 4, edi );					shr( 2, ecx );					rep.movsd();								SpaceMade:			endif;			// Okay, copy the data passed in toInsert into			// the spot we've opened up:			//			// Three variants of the actual copy code,			// based on the size of the object we're inserting:			test( %11, insertSize );			jz do4a;			test( %1, insertSize );			jz do2a;				// Okay, copy the data passed in the toInsert				// parameter into the location we've emptied up:				cld();				mov( insertSize, ecx );				mov( toInsert, esi );				mov( eax, edi );				rep.movsb();				jmp copyDone;			do2a:				// Do this if the object's size is a multiple of 2 bytes:				cld();				mov( insertSize, ecx );				mov( toInsert, esi );				shr( 1, ecx );				mov( eax, edi );				rep.movsw();				jmp copyDone;			do4a:				// Okay, copy the data passed in the toInsert				// parameter into the location we've emptied up:				cld();				mov( insertSize, ecx );				mov( toInsert, esi );				shr( 2, ecx );				mov( eax, edi );				rep.movsd();			copyDone:			pop( esi );			// Update the endData pointer to reflect the new			// array size:			mov( insertSize, eax );			add( eax, this.endData );			add( eax, this.dataSize );			// We're one element larger, so take that into			// consideration:			add( 1, this.numElements );					end _insert;		// _remove		//	Helper routine that removes a vector element from a vector.		//		// Inputs:		//		//	removeWhere-		//		Address of element to remove.		//		//	removeSize-		//		Size of element to remove.		procedure _vector._remove( removeWhere:dword; removeSize:dword );		begin _remove;			mov( removeWhere, eax );			if( eax < this.endData ) then				push( ecx );				push( edi );				push( esi );				mov( this.endData, ecx );				sub( eax, ecx );				mov( eax, esi );				add( removeSize, esi );				mov( eax, edi );				// Special cases for vectorTypes whoses sizes				// are multiples of two or four bytes:				mov( removeSize, eax );				test( %11, eax );				jz do4;				test( %1, eax );				jz do2;					rep.movsb();					jmp RemoveDone;				do2:					shr( 1, ecx );					rep.movsw();					jmp RemoveDone;				do4:					shr( 2, ecx );					rep.movsd();				RemoveDone:				pop( esi );				pop( edi );				pop( ecx );				sub( 1, this.numElements );				sub( eax, this.dataSize );				sub( eax, this.endData );			endif;		end _remove;////////////////////////////////////////////////////////////////////////////////// The vector type.//// This is a dynamic array (single dimension) whose size can change// as needed at runtime.////	Arguments:////		vectorType-//			data type for each element in the vector////		specificCapabilities-//			Enabled/disabled capabilities for this vector (used to alter//			the default settings for a vector).//////	Produces:////		Three different types:////			vectorType-//				a class for the specified vector type.////			vectorType_cursor-//				a type for cursors that point into the vectorType class.////			p_vectorType-//				a pointer to the vectorType class.////		(Note: substitute the actual parameter name for "vectorType"//		 in each of the above)////	Publically accessible fields in the class created by this macro//	(these fields should be treated as read-only):// //		isSTL_c-//			a constant, set to true, that you can use @define on to//			determine that this type is an STL type.////		capabilities_c	(compile-time)//		capabilities	(run-time)//			a bit-mapped array of booleans that specify the capabilities of//			a vector object. Test for the presence of a capability by ANDing//			with one of the *_c constants.////      typeName-//			a string holding the vectorType type name.////      containerName-//			the string "vector".////// procedures, methods, and iterators:////      procedure create( numElements:uns32 );//			Constructor for the vector class. If called with the class//			name (e.g., symbol.create(n)) then it will create the object//			on the heap and return a pointer to the new "symbol" object//			in the ESI register. If called with an actual "symbol" variable,//			this constructor initializes that variable.////			Note: if the underlying vector type is a class type, this//			constructor does *not* call the create procedure for each//			of the underlying elements in the vector. That is the caller's//			responsibility.////      method destroy;//			Destructor for the vector template class. Deallocates the storage//			associated with the object.	Note that if the underlying elements//			are a class type, this destructor does not call the destructor//			for each of those elements. You must explicitly destroy them//			prior to calling this destructor.////		method getSize;//			returns the number of vector elements in EAX. Operates in O(1) time.

⌨️ 快捷键说明

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