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

📄 kernel.hhf

📁 High Level assembly language(HLA)软件
💻 HHF
📖 第 1 页 / 共 2 页
字号:
#if( !@defined( kernel_hhf ))?kernel_hhf := true;#includeonce( "os/fs.hhf" )// kdebug is outside any namespace because we're going// to use it fairly often.// Ditto for kassert (text constant) and KDEBUG.#if( @defined( __kernel__ ))	// The following disables debugging code by default	// (KNDEBUG = true prevents emission of debug code).	// Note that "boolean(1)" is another way of saying	// "true" except it doesn't require true to be	// defined.	?KNDEBUG : boolean := boolean(1); //true	#macro kdebug( instrs );		#if( !KNDEBUG )			pushad();			pushfd();			instrs;			popfd();			popad();		#endif	#endmacro;		const	kassert	:text := 		"?linux.kassertLN := @linenumber; "		"?linux.kassertFN := @filename; "		"linux.kassert";	// The following kernel constants also exist outside the	// linux namespace because they get used so often it's too	// much of a pain to always type "linux." as a prefix to them:		kern_emerg		:text := """<0>"""; // system is unusable	kern_alert		:text := """<1>""";	// action must be take immediately	kern_crit		:text := """<2>""";	// critical conditions	kern_err		:text := """<3>""";	// error conditions	kern_warning	:text := """<4>""";	// warning conditions	kern_notice		:text := """<5>""";	// normal, but significant condition	kern_info		:text := """<6>""";	// informational	kern_debug		:text := """<6>""";	// debug-level messages	namespace linux; @fast;	val	kassertLN: dword;	kassertFN: string;		#macro kassert( expr ):skipCode,msg,fn,ln;		#if( !KNDEBUG )			readonly				msg	:string := @string:expr;				fn	:string := linux.kassertFN;				ln	:dword := linux.kassertLN;			endreadonly;						pushfd();			jt( expr ) skipCode;			pushad();			linux.printk			( 				"Kernel assertion failed: '%s' (line:%d, file: %s)\n",				msg,				ln,				fn			);			popad();						// We can't really abort the kernel, so just keep going!						skipCode:			popfd();					#endif	#endmacro;end linux;#endifnamespace linux; @fast;type		sysinfo_t:			record				uptime		:int32;				loads		:uns32[3];				totalram	:uns32;				freeram		:uns32;				shardram	:uns32;				bufferram	:uns32;				totalswap	:uns32;				freeswap	:uns32;				procs		:uns16; align(4);				totalhigh	:dword;				freehigh	:dword;				mem_unit	:dword;				align(64);			endrecord;#if( @defined( __kernel__ ))  		  // Only allow kernel-module access to the following symbols.  // Constants, types, and macros related to the  // major and minor device numbers:  const  	minorbits	:= 8;  	minormask	:= ((1 << minorbits) - 1);  	  val  	kdev_t_name	:kdev_t;  		// These macros are ugly because I decided to stick	// lots of type checking and optimization into them.	// major(dev) - extracts a major device number	// from dev object (which should be a kdev_t object).	//	//	Returns a constant if dev is a constant, otherwise	//	returns the major number in EAX.	//	// Accepts: unsigned constants, two and four byte registers,	// and memory objects whose type is kdev_t (or whatever	// kdev_t's base type is, "word" currently).	//	// Note that this macro fully knows that kdev_t is currently	// a word and must be rewritten if (when) kdev_t changes to	// some other type.	//	// Note that the major number is currently the H.O. byte	// of the kdev_t object, but there are plans to change this	// by Linux v2.6.	  	#macro major(dev):rtns;  		returns  		(  			{  				#if( @isconst( dev ))  				  					// If "dev" is a constant, just assume it's  					// an integer (rely upon HLA to catch non-int  					// consts) and return the constant as this  					// macro's RETURNS value.  If this macro were  					// consistent, I'd return the value in EAX.  					// However, by returning a constant if it  					// gets passed a constant, we can invoke  					// this macro in a constant expression.  					  					?rtns :string :=   						string( dev >> linux.minorbits );  				  				#elseif( @isreg(dev) )  				  					// It's a register.  Allow 16-bit and 32-bit  					// registers (assume they contain legitimate  					// kdev_t values).  					  					#if( @size( dev ) = 2 )  											// Do some optimization if it's 						// AX, BX, CX, or DX:						  						#if( @lowercase( @string:dev, 0 ) = "ax" )  						  							movzx( ah, eax );  							  						#elseif( @lowercase( @string:dev, 0 ) = "bx" )  						  							movzx( bh, eax );  							  						#elseif( @lowercase( @string:dev, 0 ) = "cx" )  						  							movzx( ch, eax );  							  						#elseif( @lowercase( @string:dev, 0 ) = "dx" )  						  							movzx( dh, eax );  							  							  						#else  						  							// If it's SI, DI, BP, or SP, do  							// this the hard way:  							  							movzx( dev, eax );  							shr( linux.minorbits, eax );  							  						#endif  				  					#elseif( @size( dev ) = 4 )		  								// Do some optimization if it's 						// EAX, EBX, ECX, or EDX:						  						#if( @lowercase( @string:dev, 0 ) = "eax" )  						  							movzx( ah, eax );  							  						#elseif( @lowercase( @string:dev, 0 ) = "ebx" )  						  							movzx( bh, eax );  							  						#elseif( @lowercase( @string:dev, 0 ) = "ecx" )  						  							movzx( ch, eax );  							  						#elseif( @lowercase( @string:dev, 0 ) = "edx" )  						  							movzx( dh, eax );  									  				#else		  					  						mov( dev, eax );							shr( linux.minorbits, eax );	  						  					#endif  				  					#endif					?rtns := "eax";								#elseif				( 					@typename(dev) = @typename(linux.kdev_t_name) 				  | @typename(dev) = "kdev_t" 				)									// If it's a valid memory location, then just					// extract the H.O. byte:										movzx( (type byte dev[1]), eax );					?rtns := "eax";								#else									#error					( 						"Expected a kdev_t argument, found: " +						@typename( dev )					)					?rtns := "";  				#endif  				  			}, rtns  		)  	#endmacro;  	  	  		// minor(dev) - extracts a minor device number	// from dev object (which should be a kdev_t object).	//	//	Returns a constant if dev is a constant, otherwise	//	returns the major number in EAX.	//	// Accepts: unsigned constants, two and four byte registers,	// and memory objects whose type is kdev_t (or whatever	// kdev_t's base type is, "word" currently).	//	// Note that this macro fully knows that kdev_t is currently	// a word and must be rewritten if (when) kdev_t changes to	// some other type.	//	// Note that the minor number is currently the L.O. byte	// of the kdev_t object, but there are plans to change this	// by Linux v2.6.	  	#macro minor(dev):rtns;  		returns  		(  			{  				#if( @isconst( dev ))  				  					// If "dev" is a constant, just assume it's  					// an integer (rely upon HLA to catch non-int  					// consts) and return the constant as this  					// macro's RETURNS value.  If this macro were  					// consistent, I'd return the value in EAX.  					// However, by returning a constant if it  					// gets passed a constant, we can invoke  					// this macro in a constant expression.  					  					?rtns :string :=   						string( dev & linux.minormask );  				  				#elseif( @isreg(dev) )  				  					// It's a register.  Allow 16-bit and 32-bit  					// registers (assume they contain legitimate  					// kdev_t values).  					  					#if( @size( dev ) = 2 )  											// Do some optimization if it's 						// AX, BX, CX, or DX:						  						#if( @lowercase( @string:dev, 0 ) = "ax" )  						  							movzx( al, eax );  							  						#elseif( @lowercase( @string:dev, 0 ) = "bx" )  						  							movzx( bl, eax );  							  						#elseif( @lowercase( @string:dev, 0 ) = "cx" )  						  							movzx( cl, eax );  							  						#elseif( @lowercase( @string:dev, 0 ) = "dx" )  						  							movzx( dl, eax );  							  							  						#else  						  							// If it's SI, DI, BP, or SP, do  							// this the hard way:  							  							movzx( dev, eax );  							and( linux.minormask, eax );  							  						#endif  				  					#elseif( @size( dev ) = 4 )		  								// Do some optimization if it's 						// EAX, EBX, ECX, or EDX:						  						#if( @lowercase( @string:dev, 0 ) = "eax" )  						  							movzx( al, eax );  							  						#elseif( @lowercase( @string:dev, 0 ) = "ebx" )  						  							movzx( bl, eax );  							  						#elseif( @lowercase( @string:dev, 0 ) = "ecx" )  						  							movzx( cl, eax );  							  						#elseif( @lowercase( @string:dev, 0 ) = "edx" )  						  							movzx( dl, eax );  									  				#else		  					  						mov( dev, eax );							and( linux.minormask, eax );	  						  					#endif  				  					#endif					?rtns := "eax";								#elseif				( 					@typename(dev) = @typename(linux.kdev_t_name) 				  | @typename(dev) = "kdev_t" 				)									// If it's a valid memory location, then just					// extract the L.O. byte:										movzx( (type byte dev), eax );					?rtns := "eax";								#else									#error					( 						"Expected a kdev_t argument, found: " +						@typename( dev )					)					?rtns := "";  				#endif  			}, rtns  		)  	#endmacro;  	  	  	// mkdev(ma,mi)  	//  	//	Creates a kdev_t value from the major (ma) and minor (mi)  	// values supplied as arguments.  If both arguments are constants,  	// then this macro returns a constant operand.  If either or both  	// arguments are not constants, then this function returns the  	// kdev_t value in EAX (AX contains the value which is zero-  	// extended into EAX).  	//  	//	This macro fully knows about kdev_t's internal format  	// and must be rewritten if (when) kdev_t's internal representation  	// changes.  	  	#macro mkdev(ma,mi):rtns, a, az, i, iz;  		returns  		(  			{  				#if( @isconst( ma ) & @isconst( mi ))  					?rtns:string := string( (ma << 8) | mi );  				#else  					?a  := @lowercase( @string:ma, 0 );  					?az := @size( ma );  					  					?i  := @lowercase( @string:mi, 0 );  					?iz := @size( mi );  					  					#if( az <> iz )   						  						#error( "mkdev operands must be the same size" )  						?rtns := "0";  						  					#elseif( az=1 ) // iz is also 1  					  						#if( a = "al" & i = "ah" )  						  							xchg( al, ah );  							and( $FFFF, eax );  							  						#elseif( a = "ah" & i = "al" )  							and( $FFFF, eax );  						#elseif( a = "ah" )  							  							mov( mi, al );  							and( $FFFF, eax );  						#elseif( a = "al" )  							  							mov( al, ah );  							mov( mi, al );  							and( $FFFF, eax );						#elseif( i = "al" )													mov( ma, ah );  							and( $FFFF, eax );  													#elseif( i = "ah" )													mov( ah, al );							mov( ma, ah );  							and( $FFFF, eax );  							  						#else  							  							movzx( mi, eax );  							mov( ma, ah );  							  						#endif;  						  					#elseif( az=2 ) // iz is also 2  					  						#if( a = "ax" )  						  							// We'll just have to assume  							// that mi is in the range 0..255:  							  							mov( al, ah );  							or( mi, ax );							and( $FFFF, eax );													#elseif( i = "ax" )						  							// We'll just have to assume  							// that ma is in the range 0..255:  														mov( al, ah );							or( ma, ax );							xchg( al, ah );							and( $FFFF, eax );													#elseif( @isreg( ma ) )													// ma is register, who knows							// what mi is?														mov( ma, ax );							mov( al, ah );							or( mi, ax );							and( $FFFF, eax );													#elseif( @isreg( mi ) )													// ma is memory, mi is register:														mov( (type byte ma), ah );							or( mi, ax );							and( $FFFF, eax );													#else													// Assume they're both memory:														movzx( (type byte mi), eax );							mov( (type byte ma), ah );													#endif							  							  					#elseif( az=4 ) // iz is also 4  					  						#if( a = "eax" )  						  							// We'll just have to assume  							// that mi is in the range 0..255:  							  							mov( al, ah );  							or( mi, eax );							and( $FFFF, eax );													#elseif( i = "eax" )						  							// We'll just have to assume  							// that ma is in the range 0..255:  														mov( al, ah );							or( ma, eax );							xchg( al, ah );							and( $FFFF, eax );													#elseif( @isreg( ma ) )													// ma is register, who knows							// what mi is?														mov( ma, eax );							mov( al, ah );							or( mi, eax );							and( $FFFF, eax );													#elseif( @isreg( mi ) )													// ma is memory, mi is register:														mov( (type byte ma), ah );							or( mi, eax );							and( $FFFF, eax );													#else													// Assume they're both memory:														movzx( (type byte mi), eax );							mov( (type byte ma), ah );													#endif											#endif					?rtns := "eax";									#endif							  							  			}, rtns  		)  	#endmacro;  	  	  	// kdev_t_to_nr( kdt )  	//  	// Translates a kdev_t object (currently a word)  	// to a dword object in EAX.  	  	#macro kdev_t_to_nr(dev);  		returns  		(  			{  					  		#if		  		( 		  			@typename(dev) <> @typename( linux.kdev_t_name ) 		  		)		  				  			#error		  			( 		  				"kdev_t_to_nr argument must be of type kdev_t" 		  			)		  					  		#else		  				  			movzx( dev, eax );		  					  		#endif;		  	},"eax"		)  	#endmacro;  	  	  	// to_kdev_t(dev)-  	//  	//	Translates a dword object to a kdev_t object in AX.  	  	#macro to_kdev_t(dev);

⌨️ 快捷键说明

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