📄 assembl.cpp
字号:
}
else if (pd->name[j]==name[i])
i++;
else
break;
};
if (name[i]=='\0' && (pd->name[j]=='\0' || pd->name[j]==':'))
break; // Bingo!
while (pd->name[j]!='\0' && pd->name[j]!=':')
j++;
if (pd->name[j]==':') {
j++; addrsize=4; } // Retry with 32-bit mnenonic
else {
i=0; break; // Comparison failed
};
};
if (i==0)
continue;
}
else
{ // Compare with all synonimes
j=k=0;
datasize=0; // Default settings
addrsize=4;
while (1)
{
while (pd->name[j]!=',' && pd->name[j]!='\0')
j++;
if (j-k==namelen && strnicmp(name,pd->name+k,namelen)==0)
break;
k=j+1; if (pd->name[j]=='\0')
break;
j=k;
};
if (k>j)
continue;
};
// For error diagnostics it is important to know whether mnemonic exists.
nameok++;
if (pd->arg1==NNN || pd->arg1>=PSEUDOOP)
minop=0;
else if (pd->arg2==NNN || pd->arg2>=PSEUDOOP)
{
if (minop>1) minop=1;
if (maxop<1) maxop=1;
}
else if (pd->arg3==NNN || pd->arg3>=PSEUDOOP)
{
if (minop>2) minop=2;
if (maxop<2) maxop=2;
}
else
maxop=3;
// Determine default and allowed operand size(s).
if (pd->bits==FF)
datasize=2; // Forced 16-bit size
if (pd->bits==WW || pd->bits==WS || pd->bits==W3 || pd->bits==WP)
bytesize=1; // 1-byte size allowed
else
bytesize=0; // Word/dword size only
// Check whether command operands match specified. If so, variable match
// remains zero, otherwise it contains kind of mismatch. This allows for
// better error diagnostics.
match=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 || arg>=PSEUDOOP)
{
if (op->type!=NNN) // No more arguments
match|=MA_NOP;
break;
};
if (op->type==NNN)
{
match|=MA_NOP;
break;
}; // No corresponding operand
switch (arg)
{
case REG: // Integer register in Reg field
case RCM: // Integer register in command byte
case RAC: // Accumulator (AL/AX/EAX, implicit)
if (op->type!=REG)
match|=MA_TYP;
if (arg==RAC && op->index!=REG_EAX && op->index!=8)
match|=MA_TYP;
if (bytesize==0 && op->size==1)
match|=MA_SIZ;
if (datasize==0)
datasize=op->size;
if (datasize!=op->size)
match|=MA_DIF;
break;
case RG4: // Integer 4-byte register in Reg field
if (op->type!=REG)
match|=MA_TYP;
if (op->size!=4)
match|=MA_SIZ;
if (datasize==0)
datasize=op->size;
if (datasize!=op->size)
match|=MA_DIF;
break;
case RAX: // AX (2-byte, implicit)
if (op->type!=REG || (op->index!=REG_EAX && op->index!=8))
match|=MA_TYP;
if (op->size!=2)
match|=MA_SIZ;
if (datasize==0)
datasize=op->size;
if (datasize!=op->size)
match|=MA_DIF;
break;
case RDX: // DX (16-bit implicit port address)
if (op->type!=REG || (op->index!=REG_EDX && op->index!=8))
match|=MA_TYP;
if (op->size!=2)
match|=MA_SIZ;
break;
case RCL: // Implicit CL register (for shifts)
if (op->type!=REG || (op->index!=REG_ECX && op->index!=8))
match|=MA_TYP;
if (op->size!=1)
match|=MA_SIZ;
break;
case RS0: // Top of FPU stack (ST(0))
if (op->type!=RST || (op->index!=0 && op->index!=8))
match|=MA_TYP;
break;
case RST: // FPU register (ST(i)) in command byte
if (op->type!=RST)
match|=MA_TYP;
break;
case RMX: // MMX register MMx
case R3D: // 3DNow! register MMx
if (op->type!=RMX)
match|=MA_TYP;
break;
case MRG: // Memory/register in ModRM byte
if (op->type!=MRG && op->type!=REG)
match|=MA_TYP;
if (bytesize==0 && op->size==1)
match|=MA_SIZ;
if (datasize==0)
datasize=op->size;
if (op->size!=0 && op->size!=datasize)
match|=MA_DIF;
break;
case MR1: // 1-byte memory/register in ModRM byte
if (op->type!=MRG && op->type!=REG)
match|=MA_TYP;
if (op->size!=0 && op->size!=1)
match|=MA_SIZ;
break;
case MR2: // 2-byte memory/register in ModRM byte
if (op->type!=MRG && op->type!=REG)
match|=MA_TYP;
if (op->size!=0 && op->size!=2)
match|=MA_SIZ;
break;
case MR4: // 4-byte memory/register in ModRM byte
if (op->type!=MRG && op->type!=REG)
match|=MA_TYP;
if (op->size!=0 && op->size!=4)
match|=MA_SIZ;
break;
case RR4: // 4-byte memory/register (register only)
if (op->type!=REG)
match|=MA_TYP;
if (op->size!=0 && op->size!=4)
match|=MA_SIZ;
break;
case MRJ: // Memory/reg in ModRM as JUMP target
if (op->type!=MRG && op->type!=REG)
match|=MA_TYP;
if (op->size!=0 && op->size!=4)
match|=MA_SIZ;
if ((jmpmode & 0x09)!=0)
match|=MA_JMP;
jmpmode&=0x7F;
break;
case MR8: // 8-byte memory/MMX register in ModRM
case MRD: // 8-byte memory/3DNow! register in ModRM
if (op->type!=MRG && op->type!=RMX)
match|=MA_TYP;
if (op->size!=0 && op->size!=8)
match|=MA_SIZ;
break;
case RR8: // 8-byte MMX register only in ModRM
case RRD: // 8-byte memory/3DNow! (register only)
if (op->type!=RMX)
match|=MA_TYP;
if (op->size!=0 && op->size!=8)
match|=MA_SIZ;
break;
case MMA: // Memory address in ModRM byte for LEA
if (op->type!=MRG)
match|=MA_TYP;
break;
case MML: // Memory in ModRM byte (for LES)
if (op->type!=MRG)
match|=MA_TYP;
if (op->size!=0 && op->size!=6)
match|=MA_SIZ;
if (datasize==0)
datasize=4;
else if (datasize!=4)
match|=MA_DIF;
break;
case MMS: // Memory in ModRM byte (as SEG:OFFS)
if (op->type!=MRG)
match|=MA_TYP;
if (op->size!=0 && op->size!=6)
match|=MA_SIZ;
if ((jmpmode & 0x07)!=0)
match|=MA_JMP;
jmpmode&=0x7F;
break;
case MM6: // Memory in ModRm (6-byte descriptor)
if (op->type!=MRG)
match|=MA_TYP;
if (op->size!=0 && op->size!=6)
match|=MA_SIZ;
break;
case MMB: // Two adjacent memory locations (BOUND)
if (op->type!=MRG)
match|=MA_TYP;
k=op->size;
if (ideal==0 && k>1)
k/=2;
if (k!=0 && k!=datasize)
match|=MA_DIF;
break;
case MD2: // Memory in ModRM byte (16-bit integer)
case MB2: // Memory in ModRM byte (16-bit binary)
if (op->type!=MRG)
match|=MA_TYP;
if (op->size!=0 && op->size!=2)
match|=MA_SIZ;
break;
case MD4: // Memory in ModRM byte (32-bit integer)
case MF4: // Memory in ModRM byte (32-bit float)
if (op->type!=MRG)
match|=MA_TYP;
if (op->size!=0 && op->size!=4)
match|=MA_SIZ;
break;
case MD8: // Memory in ModRM byte (64-bit integer)
case MF8: // Memory in ModRM byte (64-bit float)
if (op->type!=MRG)
match|=MA_TYP;
if (op->size!=0 && op->size!=8)
match|=MA_SIZ;
break;
case MDA: // Memory in ModRM byte (80-bit BCD)
case MFA: // Memory in ModRM byte (80-bit float)
if (op->type!=MRG)
match|=MA_TYP;
if (op->size!=0 && op->size!=10)
match|=MA_SIZ;
break;
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)
if (op->type!=MRG)
match|=MA_TYP;
if (op->size!=0)
match|=MA_SIZ;
break;
case MSO: // Source in string operands ([ESI])
if (op->type!=MRG || op->base!=REG_ESI || op->index!=-1 || op->offset!=0 || op->anyoffset!=0)
match|=MA_TYP;
if (datasize==0)
datasize=op->size;
if (op->size!=0 && op->size!=datasize)
match|=MA_DIF;
break;
case MDE: // Destination in string operands ([EDI])
if (op->type!=MRG || op->base!=REG_EDI || op->index!=-1 || op->offset!=0 || op->anyoffset!=0)
match|=MA_TYP;
if (op->segment!=SEG_UNDEF && op->segment!=SEG_ES)
match|=MA_SEG;
if (datasize==0)
datasize=op->size;
if (op->size!=0 && op->size!=datasize)
match|=MA_DIF;
break;
case MXL: // XLAT operand ([EBX+AL])
if (op->type!=MXL)
match|=MA_TYP;
break;
case IMM: // Immediate data (8 or 16/32)
case IMU: // Immediate unsigned data (8 or 16/32)
if (op->type!=IMM)
match|=MA_TYP;
break;
case VXD: // VxD service (32-bit only)
if (op->type!=IMM)
match|=MA_TYP;
if (datasize==0)
datasize=4;
if (datasize!=4)
match|=MA_SIZ;
break;
case JMF: // Immediate absolute far jump/call addr
if (op->type!=JMF)
match|=MA_TYP;
if ((jmpmode & 0x05)!=0)
match|=MA_JMP;
jmpmode&=0x7F;
break;
case JOB: // Immediate byte offset (for jumps)
if (op->type!=IMM || longjump)
match|=MA_TYP;
if ((jmpmode & 0x0A)!=0)
match|=MA_JMP;
jmpmode&=0x7F;
break;
case JOW: // Immediate full offset (for jumps)
if (op->type!=IMM)
match|=MA_TYP;
if ((jmpmode & 0x09)!=0)
match|=MA_JMP;
jmpmode&=0x7F;
break;
case IMA: // Immediate absolute near data address
if (op->type!=MRG || op->base>=0 || op->index>=0)
match|=MA_TYP;
break;
case IMX: // Immediate sign-extendable byte
if (op->type!=IMM)
match|=MA_TYP;
if (op->offset<-128 || op->offset>127)
match|=MA_RNG;
break;
case C01: // Implicit constant 1 (for shifts)
if (op->type!=IMM || (op->offset!=1 && op->anyoffset==0))
match|=MA_TYP;
break;
case IMS: // Immediate byte (for shifts)
case IM1: // Immediate byte
if (op->type!=IMM)
match|=MA_TYP;
if (op->offset<-128 || op->offset>255)
match|=MA_RNG;
break;
case IM2: // Immediate word (ENTER/RET)
if (op->type!=IMM)
match|=MA_TYP;
if (op->offset<0 || op->offset>65535)
match|=MA_RNG;
break;
case SGM: // Segment register in ModRM byte
if (op->type!=SGM)
match|=MA_TYP;
if (datasize==0)
datasize=2;
if (datasize!=2)
match|=MA_DIF;
break;
case SCM: // Segment register in command byte
if (op->type!=SGM)
match|=MA_TYP;
break;
case CRX: // Control register CRx
case DRX: // Debug register DRx
if (op->type!=arg)
match|=MA_TYP;
if (datasize==0)
datasize=4;
if (datasize!=4)
match|=MA_DIF;
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;
default: // Undefined type of operand
strcpy(errtext,"Internal Assembler error");
goto error;
}; // End of switch (arg)
if ((jmpmode & 0x80)!=0)
match|=MA_JMP;
if (match!=0)
break; // Some of the operands doesn't match
}; // End of operand matching loop
if (match==0)
{ // Exact match found
if (attempt>0)
{
--attempt;
nameok=0;
} // Well, try to find yet another match
else
break;
};
}; // End of command search loop
// Check whether some error was detected. If several errors were found
// similtaneously, report one (roughly in order of significance).
if (nameok==0)
{ // Mnemonic unavailable
strcpy(errtext,"Unrecognized command");
asmcmd=nameend; goto error;
};
if (match!=0)
{ // Command not found
if (minop>0 && aop[minop-1].type==NNN)
strcpy(errtext,"Too few operands");
else if (maxop<3 && aop[maxop].type!=NNN)
strcpy(errtext,"Too many operands");
else if (nameok>1) // More that 1 command
strcpy(errtext,"Command does not support given operands");
else if (match & MA_JMP)
strcpy(errtext,"Invalid jump size modifier");
else if (match & MA_NOP)
strcpy(errtext,"Wrong number of operands");
else if (match & MA_TYP)
strcpy(errtext,"Command does not support given operands");
else if (match & MA_NOS)
strcpy(errtext,"Please specify operand size");
else if (match & MA_SIZ)
strcpy(errtext,"Bad operand size");
else if (match & MA_DIF)
strcpy(errtext,"Different size of operands");
else if (match & MA_SEG)
strcpy(errtext,"Invalid segment register");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -