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

📄 assembl.cpp

📁 实现了屏幕截取
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			};
			asmcmd++;
			idata=hex; scan=SCAN_ICONST;
			while (*asmcmd==' ' || *asmcmd=='\t')
				asmcmd++;
			return; 
		};
		if (*asmcmd=='.') 
		{                // Force decimal number
			if (base==16 || maxdigit>9) 
			{
				asmerror="Not a decimal number";
				scan=SCAN_ERR;
				return;
			};
			asmcmd++;
			if (isdigit(*asmcmd) || toupper(*asmcmd)=='E')
			{
				divisor=1.0;
				while (isdigit(*asmcmd)) 
				{     // Floating-point number
					divisor/=10.0;
					floating+=divisor*(*asmcmd-'0');
					asmcmd++; 
				};
				if (toupper(*asmcmd)=='E') 
				{
					asmcmd++;
					if (*asmcmd=='-') 
					{
						base=-1;
						asmcmd++;
					}
					else 
						base=1;
					if (!isdigit(*asmcmd))
					{
						asmerror="Invalid exponent";
						scan=SCAN_ERR; 
						return;
					};
					decimal=0;
					while (isdigit(*asmcmd))
					{
						if (decimal<65536L)
							decimal=decimal*10+(*asmcmd++)-'0';
					};

					floating*=powl(decimal*base,1);
				};
				fdata=floating;
				scan=SCAN_FCONST;
				return; 
			}
			else
			{
				idata=decimal;
				scan=SCAN_DCONST;
				while (*asmcmd==' ' || *asmcmd=='\t') 
					asmcmd++;
				return;
			};
		};
		idata=hex; 
		scan=SCAN_ICONST;       // Default is hexadecimal
		while (*asmcmd==' ' || *asmcmd=='\t') 
			asmcmd++;
		return;
	}
	else if (*asmcmd=='\'') 
	{            // Character constant
		asmcmd++;
		if (*asmcmd=='\0' || (*asmcmd=='\\' && asmcmd[1]=='\0'))
		{
			asmerror="Unterminated character constant"; 
			scan=SCAN_ERR;
			return;
		};
		if (*asmcmd=='\'')
		{
			asmerror="Empty character constant";
			scan=SCAN_ERR; 
			return;
		};
		if (*asmcmd=='\\') 
			asmcmd++;
		idata=*asmcmd++; 
		if (*asmcmd!='\'') 
		{
			asmerror="Unterminated character constant";
			scan=SCAN_ERR; 
			return;
		};
		asmcmd++;
		while (*asmcmd==' ' || *asmcmd=='\t') 
			asmcmd++;
		scan=SCAN_ICONST;
		return;
	}
	else
	{                               // Any other character or combination
		idata=sdata[0]=*asmcmd++; sdata[1]=sdata[2]='\0';
		if (idata=='|' && *asmcmd=='|')
		{
			idata='||'; prio=10;             // '||'
			sdata[1]=*asmcmd++;
		}
		else if (idata=='&' && *asmcmd=='&')
		{
			idata='&&'; prio=9;              // '&&'
			sdata[1]=*asmcmd++;
		}
		else if (idata=='=' && *asmcmd=='=') 
		{
			idata='=='; prio=5;              // '=='
			sdata[1]=*asmcmd++; 
		}
		else if (idata=='!' && *asmcmd=='=')
		{
			idata='!='; prio=5;              // '!='
			sdata[1]=*asmcmd++;
		}
		else if (idata=='<' && *asmcmd=='=')
		{
			idata='<='; prio=4;              // '<='
			sdata[1]=*asmcmd++;
		}
		else if (idata=='>' && *asmcmd=='=') 
		{
			idata='>='; prio=4;              // '>='
			sdata[1]=*asmcmd++;
		}
		else if (idata=='<' && *asmcmd=='<') 
		{
			idata='<<'; prio=3;              // '<<'
			sdata[1]=*asmcmd++; 
		}
		else if (idata=='>' && *asmcmd=='>')
		{
			idata='>>'; prio=3;              // '>>'
			sdata[1]=*asmcmd++; 
		}
		else if (idata=='|') 
			prio=8;       // '|'
		else if (idata=='^') 
			prio=7;       // '^'
		else if (idata=='&') 
			prio=6;       // '&'
		else if (idata=='<')
		{
			if (*asmcmd=='&') 
			{              // Import pseudolabel (for internal use)
				if ((mode & SA_IMPORT)==0)
				{
					asmerror="Syntax error";
					scan=SCAN_ERR; return;
				};
				asmcmd++; i=0;
				while (*asmcmd!='\0' && *asmcmd!='>')
				{
					sdata[i++]=*asmcmd++;
					if (i>=sizeof(sdata))
					{
						asmerror="Too long import name"; 
						scan=SCAN_ERR; 
						return;
					};
				};
				if (*asmcmd!='>') 
				{
					asmerror="Unterminated import name";
					scan=SCAN_ERR; 
					return;
				};
				asmcmd++;
				sdata[i]='\0';
				scan=SCAN_IMPORT; 
				return;
			}
			else prio=4;
		}                   // '<'
		else if (idata=='>')
			prio=4;       // '>'
		else if (idata=='+')
			prio=2;       // '+'
		else if (idata=='-')
			prio=2;       // '-'
		else if (idata=='*') 
			prio=1;       // '*'
		else if (idata=='/')
			prio=1;       // '/'
		else if (idata=='%') 
			prio=1;       // '%'
		else if (idata==']')
		{
			pcmd=asmcmd; 
			Scanasm(SA_NAME);
			if (scan!=SCAN_SYMB || idata!='[')
			{
				idata=']';
				asmcmd=pcmd; 
				prio=0;
			}
			else
			{
				idata='+'; prio=2;             // Translate '][' to '+'
			};
		}
		else 
			prio=0;                       // Any other character
		scan=SCAN_SYMB;
		return;
	};
};

// Fetches one complete operand from the input line and fills in structure op
// with operand's data. Expects that first token of the operand is already
// scanned. Supports operands in generalized form (for example, R32 means any
// of general-purpose 32-bit integer registers).
static void Parseasmoperand(t_asmoperand *op) 
{
	int i,j,bracket,sign,xlataddr;
	int reg,r[9];
	long offset;
	if (scan==SCAN_EOL || scan==SCAN_ERR)
		return;                            // No or bad operand
	// Jump or call address may begin with address size modifier(s) SHORT, LONG,
	// NEAR and/or FAR. Not all combinations are allowed. After operand is
	// completely parsed, this function roughly checks whether modifier is
	// allowed. Exact check is done in Assemble().
	if (scan==SCAN_JMPSIZE) 
	{
		j=0;
		while (scan==SCAN_JMPSIZE)
		{
			j|=idata;                        // Fetch all size modifiers
			Scanasm(0); 
		};
		if (
			((j & 0x03)==0x03) ||            // Mixed SHORT and LONG
			((j & 0x0C)==0x0C) ||            // Mixed NEAR and FAR
			((j & 0x09)==0x09)               // Mixed FAR and SHORT
			) 
		{
			asmerror="Invalid combination of jump address modifiers";
			scan=SCAN_ERR;
			return;
		};
		if ((j & 0x08)==0)
			j|=0x04;        // Force NEAR if not FAR
		op->jmpmode=j; 
	};
	// Simple operands are either register or constant, their processing is
	// obvious and straightforward.
	if (scan==SCAN_REG8 || scan==SCAN_REG16 || scan==SCAN_REG32)
	{
		op->type=REG; 
		op->index=idata;     // Integer general-purpose register
		if (scan==SCAN_REG8)
			op->size=1;
		else if (scan==SCAN_REG16)
			op->size=2;
		else 
			op->size=4;
	}
	else if (scan==SCAN_FPU) 
	{           // FPU register
		op->type=RST; 
		op->index=idata;
	}
	else if (scan==SCAN_MMX) 
	{           // MMX or 3DNow! register
		op->type=RMX; 
		op->index=idata;
	}
	else if (scan==SCAN_CR)
	{            // Control register
		op->type=CRX; 
		op->index=idata;
	}
	else if (scan==SCAN_DR) 
	{            // Debug register
		op->type=DRX;
		op->index=idata;
	}
	else if (scan==SCAN_SYMB && idata=='-')
	{
		Scanasm(0);                        // Negative constant
		if (scan!=SCAN_ICONST && scan!=SCAN_DCONST && scan!=SCAN_OFS)
		{
			asmerror="Integer number expected";
			scan=SCAN_ERR;
			return;
		};
		op->type=IMM; 
		op->offset=-idata;
		if (scan==SCAN_OFS)
			op->anyoffset=1; 
	}
	else if (scan==SCAN_SYMB && idata=='+') 
	{
		Scanasm(0);                        // Positive constant
		if (scan!=SCAN_ICONST && scan!=SCAN_DCONST && scan!=SCAN_OFS)
		{
			asmerror="Integer number expected";
			scan=SCAN_ERR;
			return; 
		};
		op->type=IMM; 
		op->offset=idata;
		if (scan==SCAN_OFS) 
			op->anyoffset=1;
	}
	else if (scan==SCAN_ICONST || scan==SCAN_DCONST || scan==SCAN_OFS) 
	{
		j=idata;
		if (scan==SCAN_OFS) 
			op->anyoffset=1;
		Scanasm(0);
		if (scan==SCAN_SYMB && idata==':')
		{
			Scanasm(0);                      // Absolute long address (seg:offset)
			if (scan!=SCAN_ICONST && scan!=SCAN_DCONST && scan!=SCAN_OFS) 
			{
				asmerror="Integer address expected";
				scan=SCAN_ERR;
				return;
			};
			op->type=JMF; 
			op->offset=idata;
			op->segment=j;
			if (scan==SCAN_OFS) 
				op->anyoffset=1;
		}
		else 
		{
			op->type=IMM; 
			op->offset=j;      // Constant without sign
			return;                          // Next token already scanned
		};
	}
	else if (scan==SCAN_FCONST)
	{
		asmerror="Floating-point numbers are not allowed in command";
		scan=SCAN_ERR;
		return; 
	}
	// Segment register or address.
	else if (scan==SCAN_SEG || scan==SCAN_OPSIZE || (scan==SCAN_SYMB && idata=='[') ) 
	{                                  // Segment register or address
		bracket=0;
		if (scan==SCAN_SEG)
		{
			j=idata; Scanasm(0);
			if (scan!=SCAN_SYMB || idata!=':')
			{
				op->type=SGM; op->index=j;     // Segment register as operand
				return; 
			};                     // Next token already scanned
			op->segment=j; 
			Scanasm(0); 
		};
		// Scan 32-bit address. This parser does not support 16-bit addresses.
		// First of all, get size of operand (optional), segment register (optional)
		// and opening bracket (required).
		while (1)
		{
			if (scan==SCAN_SYMB && idata=='[')
			{
				if (bracket)
				{                 // Bracket
					asmerror="Only one opening bracket allowed";
					scan=SCAN_ERR; return; 
				};
				bracket=1;
			}
			else if (scan==SCAN_OPSIZE)
			{
				if (op->size!=0) 
				{             // Size of operand
					asmerror="Duplicated size modifier";
					scan=SCAN_ERR;
					return; 
				};
				op->size=idata;
			}
			else if (scan==SCAN_SEG)
			{
				if (op->segment!=SEG_UNDEF) 
				{  // Segment register
					asmerror="Duplicated segment register";
					scan=SCAN_ERR; 
					return; 
				};
				op->segment=idata; Scanasm(0);
				if (scan!=SCAN_SYMB || idata!=':') 
				{
					asmerror="Semicolon expected";
					scan=SCAN_ERR; return;
				};
			}
			else if (scan==SCAN_ERR)
				return;
			else 
				break;                      // None of expected address elements
			Scanasm(0);
		};
		if (bracket==0)
		{
			asmerror="Address expression requires brackets";
			scan=SCAN_ERR; 
			return; 
		};
		// Assembling a 32-bit address may be a kind of nigthmare, due to a large
		// number of allowed forms. Parser collects immediate offset in op->offset
		// and count for each register in array r[]. Then it decides whether this
		// combination is valid and determines scale, index and base. Assemble()
		// will use these numbers to select address form (with or without SIB byte,
		// 8- or 32-bit offset, use segment prefix or not). As a useful side effect
		// of this technique, one may specify, for example, [EAX*5] which will
		// correctly assemble to [EAX*4+EAX].
		for (i=0; i<=8; i++) r[i]=0;
		sign='+';                          // Default sign for the first operand
		xlataddr=0;
		while (1) 
		{                        // Get SIB and offset
			if (scan==SCAN_SYMB && (idata=='+' || idata=='-'))
			{
				sign=idata; Scanasm(0);
			};
			if (scan==SCAN_ERR) 
				return;
			if (sign=='?')
			{
				asmerror="Syntax error"; 
				scan=SCAN_ERR;
				return; };
				// Register AL appears as part of operand of (seldom used) command XLAT.
				if (scan==SCAN_REG8 && idata==REG_EAX) 

⌨️ 快捷键说明

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