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

📄 assembl.cpp

📁 实现了屏幕截取
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		else if (match & MA_RNG)
			strcpy(errtext,"Constant out of expected range");
		else
			strcpy(errtext,"Erroneous command");
		goto error;
	};
	// Exact match found. Now construct the code.
	hasrm=0;                             // Whether command has ModR/M byte
	hassib=0;                            // Whether command has SIB byte
	dispsize=0;                          // Size of displacement (if any)
	immsize=0;                           // Size of immediate data (if any)
	segment=SEG_UNDEF;                   // Necessary segment prefix
	jmpsize=0;                           // No relative jumps
	memset(tcode,0,sizeof(tcode));
	*(ulong *)tcode=pd->code & pd->mask;
	memset(tmask,0,sizeof(tmask));
	*(ulong *)tmask=pd->mask;
	i=pd->len-1;                         // Last byte of command itself
	if (rep) i++;                        // REPxx prefixes count as extra byte
	// In some cases at least one operand must have explicit size declaration (as
	// in MOV [EAX],1). This preliminary check does not include all cases.
	if (pd->bits==WW || pd->bits==WS || pd->bits==WP)
	{
		if (datasize==0) 
		{
			strcpy(errtext,"Please specify operand size");
			goto error; 
		}
		else if (datasize>1)
			tcode[i]|=0x01;                  // WORD or DWORD size of operands
		tmask[i]|=0x01;
	}
	else if (pd->bits==W3) 
	{
		if (datasize==0) 
		{
			strcpy(errtext,"Please specify operand size");
			goto error; 
		}
		else if (datasize>1)
			tcode[i]|=0x08;                  // WORD or DWORD size of operands
		tmask[i]|=0x08;
	};
	// Present suffix of 3DNow! command as immediate byte operand.
	if ((pd->type & C_TYPEMASK)==C_NOW)
	{
		immsize=1;
		immediate=(pd->code>>16) & 0xFF;
	};
	// Process operands again, this time constructing the code.
	anydisp=anyimm=anyjmp=0;
	for (j=0; j<3; j++)
	{                // Up to 3 operands
		op=aop+j;
		if (j==0) 
			arg=pd->arg1;
		else if 
			(j==1) arg=pd->arg2;
		else
			arg=pd->arg3;
		if (arg==NNN)
			break;               // All operands processed
		switch (arg)
		{
		case REG:                        // Integer register in Reg field
		case RG4:                        // Integer 4-byte register in Reg field
		case RMX:                        // MMX register MMx
		case R3D:                        // 3DNow! register MMx
		case CRX:                        // Control register CRx
		case DRX:                        // Debug register DRx
			hasrm=1;
			if (op->index<8) 
			{
				tcode[i+1]|=(char)(op->index<<3); 
				tmask[i+1]|=0x38; 
			};
			break;
		case RCM:                        // Integer register in command byte
		case RST:                        // FPU register (ST(i)) in command byte
			if (op->index<8)
			{
				tcode[i]|=(char)op->index; 
				tmask[i]|=0x07; 
			};
			break;
		case RAC:                        // Accumulator (AL/AX/EAX, implicit)
		case RAX:                        // AX (2-byte, implicit)
		case RDX:                        // DX (16-bit implicit port address)
		case RCL:                        // Implicit CL register (for shifts)
		case RS0:                        // Top of FPU stack (ST(0))
		case MDE:                        // Destination in string op's ([EDI])
		case C01:                        // Implicit constant 1 (for shifts)
			break;                         // Simply skip implicit operands
		case MSO:                        // Source in string op's ([ESI])
		case MXL:                        // XLAT operand ([EBX+AL])
			if (op->segment!=SEG_UNDEF && op->segment!=SEG_DS)
				segment=op->segment;
			break;
		case MRG:                        // Memory/register in ModRM byte
		case MRJ:                        // Memory/reg in ModRM as JUMP target
		case MR1:                        // 1-byte memory/register in ModRM byte
		case MR2:                        // 2-byte memory/register in ModRM byte
		case MR4:                        // 4-byte memory/register in ModRM byte
		case RR4:                        // 4-byte memory/register (register only)
		case MR8:                        // 8-byte memory/MMX register in ModRM
		case RR8:                        // 8-byte MMX register only in ModRM
		case MRD:                        // 8-byte memory/3DNow! register in ModRM
		case RRD:                        // 8-byte memory/3DNow! (register only)
			hasrm=1;
			if (op->type!=MRG) 
			{           // Register in ModRM byte
				tcode[i+1]|=0xC0;
				tmask[i+1]|=0xC0;
				if (op->index<8) 
				{
					tcode[i+1]|=(char)op->index; 
					tmask[i+1]|=0x07; 
				};
				break;
			};                             // Note: NO BREAK, continue with address
		case MMA:                        // Memory address in ModRM byte for LEA
		case MML:                        // Memory in ModRM byte (for LES)
		case MMS:                        // Memory in ModRM byte (as SEG:OFFS)
		case MM6:                        // Memory in ModRm (6-byte descriptor)
		case MMB:                        // Two adjacent memory locations (BOUND)
		case MD2:                        // Memory in ModRM byte (16-bit integer)
		case MB2:                        // Memory in ModRM byte (16-bit binary)
		case MD4:                        // Memory in ModRM byte (32-bit integer)
		case MD8:                        // Memory in ModRM byte (64-bit integer)
		case MDA:                        // Memory in ModRM byte (80-bit BCD)
		case MF4:                        // Memory in ModRM byte (32-bit float)
		case MF8:                        // Memory in ModRM byte (64-bit float)
		case MFA:                        // Memory in ModRM byte (80-bit float)
		case MFE:                        // Memory in ModRM byte (FPU environment)
		case MFS:                        // Memory in ModRM byte (FPU state)
		case MFX:                        // Memory in ModRM byte (ext. FPU state)
			hasrm=1; displacement=op->offset; anydisp=op->anyoffset;
			if (op->base<0 && op->index<0) 
			{
				dispsize=4;                  // Special case of immediate address
				if (op->segment!=SEG_UNDEF && op->segment!=SEG_DS)
					segment=op->segment;
				tcode[i+1]|=0x05;
				tmask[i+1]|=0xC7; }
			else if (op->index<0 && op->base!=REG_ESP) 
			{
				tmask[i+1]|=0xC0;            // SIB byte unnecessary
				if (op->offset==0 && op->anyoffset==0 && op->base!=REG_EBP)
					;                          // [EBP] always requires offset
				else if ((constsize & 1)!=0 && ((op->offset>=-128 && op->offset<128) || op->anyoffset!=0) )
				{
					tcode[i+1]|=0x40;          // Disp8
					dispsize=1;
				}
				else 
				{
					tcode[i+1]|=0x80;          // Disp32
					dispsize=4;
				};
				if (op->base<8)
				{
					if (op->segment!=SEG_UNDEF && op->segment!=addr32[op->base].defseg)
						segment=op->segment;
					tcode[i+1]|= (char)op->base;          // Note that case [ESP] has base<0.
					tmask[i+1]|=0x07;
				}
				else 
					segment=op->segment; 
			}
			else 
			{                         // SIB byte necessary
				hassib=1;
				if (op->base==REG_EBP &&     // EBP as base requires offset, optimize
					op->index>=0 && op->scale==1 && op->offset==0 && op->anyoffset==0)
				{
					op->base=op->index; op->index=REG_EBP;
				};
				if (op->index==REG_ESP &&    // ESP cannot be an index, reorder
					op->scale<=1) 
				{
					op->index=op->base; op->base=REG_ESP; op->scale=1;
				};
				if (op->base<0 &&            // No base means 4-byte offset, optimize
					op->index>=0 && op->scale==2 &&
					op->offset>=-128 && op->offset<128 && op->anyoffset==0)
				{
					op->base=op->index; op->scale=1;
				};
				if (op->index==REG_ESP)
				{    // Reordering was unsuccessfull
					strcpy(errtext,"Invalid indexing mode");
					goto error;
				};
				if (op->base<0) 
				{
					tcode[i+1]|=0x04;
					dispsize=4; 
				}
				else if (op->offset==0 && op->anyoffset==0 && op->base!=REG_EBP)
					tcode[i+1]|=0x04;          // No displacement
				else if ((constsize & 1)!=0 && ((op->offset>=-128 && op->offset<128) || op->anyoffset!=0) )
				{
					tcode[i+1]|=0x44;          // Disp8
					dispsize=1;
				}
				else
				{
					tcode[i+1]|=0x84;          // Disp32
					dispsize=4; };
					tmask[i+1]|=0xC7;            // ModRM completed, proceed with SIB
					if (op->scale==2)
						tcode[i+2]|=0x40;
					else if (op->scale==4)
						tcode[i+2]|=0x80;
					else if (op->scale==8)
						tcode[i+2]|=0xC0;
					tmask[i+2]|=0xC0;
					if (op->index<8) 
					{
						if (op->index<0)
							op->index=0x04;
						tcode[i+2]|=(char)(op->index<<3);
						tmask[i+2]|=0x38;
					};
					if (op->base<8) 
					{
						if (op->base<0)
							op->base=0x05;
						if (op->segment!=SEG_UNDEF && op->segment!=addr32[op->base].defseg)
							segment=op->segment;
						tcode[i+2]|=(char)op->base;
						tmask[i+2]|=0x07;
					}
					else 
						segment=op->segment; 
			};
			break;
		case IMM:                        // Immediate data (8 or 16/32)
		case IMU:                        // Immediate unsigned data (8 or 16/32)
		case VXD:                        // VxD service (32-bit only)
			if (datasize==0 && pd->arg2==NNN && (pd->bits==SS || pd->bits==WS))
				datasize=4;
			if (datasize==0)
			{
				strcpy(errtext,"Please specify operand size");
				goto error;
			};
			immediate=op->offset; anyimm=op->anyoffset;
			if (pd->bits==SS || pd->bits==WS) 
			{
				if (datasize>1 && (constsize & 2)!=0 && ((immediate>=-128 && immediate<128) || op->anyoffset!=0)) 
				{
					immsize=1; tcode[i]|=0x02;
				}
				else
					immsize=datasize;
				tmask[i]|=0x02;
			}
			else
				immsize=datasize;
			break;
		case IMX:                        // Immediate sign-extendable byte
		case IMS:                        // Immediate byte (for shifts)
		case IM1:                        // Immediate byte
			if (immsize==2)                // To accomodate ENTER instruction
				immediate=(immediate & 0xFFFF) | (op->offset<<16);
			else
				immediate=op->offset;
			anyimm|=op->anyoffset;
			immsize++;
			break;
		case IM2:                        // Immediate word (ENTER/RET)
			immediate=op->offset; anyimm=op->anyoffset;
			immsize=2; 
			break;
		case IMA:                        // Immediate absolute near data address
			if (op->segment!=SEG_UNDEF && op->segment!=SEG_DS)
				segment=op->segment;
			displacement=op->offset;
			anydisp=op->anyoffset;
			dispsize=4;
			break;
		case JOB:                        // Immediate byte offset (for jumps)
			jmpoffset=op->offset; 
			anyjmp=op->anyoffset;
			jmpsize=1; 
			break;
		case JOW:                        // Immediate full offset (for jumps)
			jmpoffset=op->offset;
			anyjmp=op->anyoffset;
			jmpsize=4;
			break;
		case JMF:                        // Immediate absolute far jump/call addr
			displacement=op->offset;
			anydisp=op->anyoffset;
			dispsize=4;
			immediate=op->segment;
			anyimm=op->anyoffset; 
			immsize=2;
			break;
		case SGM:                        // Segment register in ModRM byte
			hasrm=1;
			if (op->index<6)
			{
				tcode[i+1]|=(char)(op->index<<3); 
				tmask[i+1]|=0x38;
			};
			break;
		case SCM:                        // Segment register in command byte
			if (op->index==SEG_FS || op->index==SEG_GS) 
			{
				tcode[0]=0x0F; tmask[0]=0xFF;
				i=1;
				if (strcmp(name,"PUSH")==0)
					tcode[i]=(char)((op->index<<3) | 0x80);
				else
					tcode[i]=(char)((op->index<<3) | 0x81);
				tmask[i]=0xFF; 
			}
			else if (op->index<6) 
			{
				if (op->index==SEG_CS && strcmp(name,"POP")==0)
				{
					strcpy(errtext,"Unable to POP CS");
					goto error;
				};
				tcode[i]=(char)((tcode[i] & 0xC7) | (op->index<<3)); }
			else
			{
				tcode[i]&=0xC7;
				tmask[i]&=0xC7;
			};
			break;
		case PRN:                        // Near return address (pseudooperand)
		case PRF:                        // Far return address (pseudooperand)
		case PAC:                        // Accumulator (AL/AX/EAX, pseudooperand)
		case PAH:                        // AH (in LAHF/SAHF, pseudooperand)
		case PFL:                        // Lower byte of flags (pseudooperand)
		case PS0:                        // Top of FPU stack (pseudooperand)
		case PS1:                        // ST(1) (pseudooperand)
		case PCX:                        // CX/ECX (pseudooperand)
		case PDI:                        // EDI (pseudooperand in MMX extentions)
			break;                         // Simply skip preudooperands
		default:                         // Undefined type of operand
			strcpy(errtext,"Internal Assembler error");
			goto error;
		};
	};
	// Gather parts of command together in the complete command.
	j=0;
	if (lock!=0) 
	{                       // Lock prefix specified
		model->code[j]=0xF0;
		model->mask[j]=0xFF; 
		j++;
	};
	if (datasize==2 && pd->bits!=FF)
	{   // Data size prefix necessary
		model->code[j]=0x66;
		model->mask[j]=0xFF; 
		j++; 
	};
	if (addrsize==2)
	{                   // Address size prefix necessary
		model->code[j]=0x67;
		model->mask[j]=0xFF;
		j++;
	};
	if (segment!=SEG_UNDEF) 
	{            // Segment prefix necessary
		if (segment==SEG_ES) 
			model->code[j]=0x26;
		else if (segment==SEG_CS) 
			model->code[j]=0x2E;
		else if (segment==SEG_SS)
			model->code[j]=0x36;
		else if (segment==SEG_DS)
			model->code[j]=0x3E;
		else if (segment==SEG_FS)
			model->code[j]=0x64;
		else if (segment==SEG_GS)
			model->code[j]=0x65;
		else 
		{ 
			strcpy(errtext,"Internal Assembler error");
			goto error;
		};
		model->mask[j]=0xFF; 
		j++; 
	};
	if (dispsize>0)
	{
		memcpy(tcode+i+1+hasrm+hassib,&displacement,dispsize);
		if (anydisp==0) 
			memset(tmask+i+1+hasrm+hassib,0xFF,dispsize);
	};
	if (immsize>0) 
	{
		if (immsize==1)
			l=0xFFFFFF00L;
		else if (immsize==2)
			l=0xFFFF0000L;
		else 
			l=0L;
		if ((immediate & l)!=0 && (immediate & l)!=l)
		{
			strcpy(errtext,"Constant does not fit into operand");
			goto error;
		};
		memcpy(tcode+i+1+hasrm+hassib+dispsize,&immediate,immsize);
		if (anyimm==0)
			memset(tmask+i+1+hasrm+hassib+dispsize,0xFF,immsize);
	};
	i=i+1+hasrm+hassib+dispsize+immsize;
	jmpoffset=jmpoffset-(i+j+jmpsize);
	model->jmpsize=jmpsize;
	model->jmpoffset=jmpoffset;
	model->jmppos=i+j;
	if (jmpsize!=0)
	{
		if (ip!=0)
		{
			jmpoffset=jmpoffset-ip;
			if (jmpsize==1 && anyjmp==0 && (jmpoffset<-128 || jmpoffset>=128))
			{
				if (longjump==0 && (jmpmode & 0x03)==0)
				{
					longjump=1;
					goto retrylongjump;
				};
				sprintf(errtext,"Relative jump out of range, use %s LONG form",name);
				goto error;
			};
			memcpy(tcode+i,&jmpoffset,jmpsize);
		};
		if 

⌨️ 快捷键说明

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