kolibrios-fun/programs/develop/c--/trunk/generate.h--

1719 lines
35 KiB
Plaintext
Raw Normal View History

dword ACTUALMNEMDESC; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><E1A0AD><><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
byte ACTUALMNEMONIC; // <20><><EFBFBD><><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
byte OPERANDSIZE; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD>(B,W,D,BW,WB,DW)
byte OPDESC[3]; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD> (R,E,D,CC,SR,TR,DR,CR)
byte OPDATA[3]; // <20><><EFBFBD><EFBFBD><EFBFBD><E0ACA0><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><E0A0AD> (RG,CO,EA)
dword OPCONST[3]; // <20><><EFBFBD><EFBFBD><E7A5AD> <20><><EFBFBD><EFBFBD><EFBFBD><E2A0AD> <20> <20><><EFBFBD><EFBFBD><E0A0AD>
byte OPCONSTFLAG[3]; // <20><><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><E2A0AD> <20> <20><><EFBFBD><EFBFBD><E0A0AD>
byte OPCONSTSIZE[3]; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E0ADAE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E2A0AD> <20> <20><><EFBFBD><EFBFBD><E0A0AD>
byte OPPOST[3];
dword OPPOSTREF[3];
byte PFLAG; // <20><><EFBFBD><EFBFBD><E7A5AD> P-䫠<><E4ABA0> (<28><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>).
byte RANDFLAG; // TRUE: RAND: <20><EFBFBD><E0A5A1><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> 0x66
byte ADDRFLAG; // TRUE: ADDR: <20><EFBFBD><E0A5A1><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> 0x67
byte WBIT; // <20><><EFBFBD> WORD <20> OPCODE
byte DBIT; // <20><><EFBFBD> DIRECTION <20> OPCODE
byte OPLENGTH; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD> <20><><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
byte EA_M; // <20><><EFBFBD><EFBFBD> XRM
byte EA_X;
byte EA_R; // R NIBBLE IN XRM BYTE.
byte EA_S; //SEGMENT REGISTER
byte EA_R2; //BASE REGISTER
byte EA_I; //INDEX REGISTER
byte EADESC[2]; //CONTAINS INFORMATION ABOUT AN PARSED EFFECTIVE ADRESS.
byte EALENGTH; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⢮ ॣ<><E0A5A3><EFBFBD><20> EA
byte EA_SIBFLAG; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Sib <20> 32-<2D><><EFBFBD> EA
byte EA_SCALING; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> Sib
dword EA_SCALE; // <20><><EFBFBD><EFBFBD><E7A5AD> <20><><EFBFBD> Scale <20> Sib
dword EADescInd; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> EADESC
byte SEGREGISTER; // SEGMENT OVERRIDE PREFIX NEEDED OR 0.
byte SYSRNUM; // CONTROL/DEBUG/TASKREG INDEX
byte SYSRTYPE; // SYSTEM REGISTER TYPE (CR,CR4,DR,TR)
byte SYSRCODE; // ENCODED REGISTER TYPE
byte OVERRIDE; //SEGMENT OVERRIDE PREFIX NEEDED OR 0.
dword opDescInd;
dword prevTok;
// ----- <20><><EFBFBD><E1A5AC><EFBFBD><EFBFBD><E0AEA2><EFBFBD><EFBFBD> <20><><EFBFBD>
Asm(dword str)
byte holdcha;
byte source[256],s[STRLEN],s2[STRLEN];
{
lstrcpyA(#source,str);
IF(list){
fprint(mapfile,"\t//\t");
fprint(mapfile,str);
fprint(mapfile,"\n");
}
holdcha=cha2; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E0A0A7><EFBFBD><EFBFBD>
$PUSH linenum2,inptr2,number,tok2,tok,input,inptr,currmod,linenumber,
endoffile,displaytokerrors,type;
lstrcpyA(#s,#string);
lstrcpyA(#s2,#string2);
input=#source; //ࠧ<><E0A0A7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
inptr = input;
inptr2=input;
endoffile=0; // <20><> <20><><EFBFBD><><E4A0A9>
NextChar();
cha2 = cha;
inptr2=inptr;
linenum2 = 1;
for(;;){
NextTok();
IF(tok==tk_mnemonics)DoMnemonics();
ELSE IF(tok==tk_eof)BREAK;
ELSE IF(tok==tk_locallabel)DoLocalPost();
ELSE IF(tok!=tk_semicolon)preerror("ASM: Bad input format\n");
}
lstrcpyA(#string,#s); //<2F><><EFBFBD><EFBFBD><E2A0AD><EFBFBD><EFBFBD><EFBFBD>
lstrcpyA(#string2,#s2);
$POP type,displaytokerrors,endoffile,linenumber,currmod,inptr,input,
tok,tok2,number,inptr2,linenum2;
cha2=holdcha;
}
DoLocalPost()
dword i;
{
tok = tk_number;
number = outptr-output+OptImageBase+OptBaseOfCode;
ESI=localptr;
DSDWORD[ESI+localtok] = tok;
DSDWORD[ESI+localnumber] = number;
i=0;
WHILE(i<posts){
ECX=i<<2+postnum;
EAX=DSDWORD[ECX];
IF(EAX==localptr){
DSDWORD[ECX]=number;
EBX=i<<2+posttype;
DSDWORD[EBX]=POST_LOC;
}
i++;
}
NextTok();
NextTok();
}
// ---- <20><><EFBFBD><E2A0AD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFA2AB><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4A8AA><EFBFBD><EFBFBD>
SetPost(dword ref,ptype)
{
IF(posts >= MAXPOSTS)maxwordpostserror();
EBX=posts<<2+postloc;
DSDWORD[EBX] = outptr;
EBX=posts<<2+postnum;
DSDWORD[EBX] = ref;
EBX=posts<<2+posttype;
DSDWORD[EBX] = ptype;
posts++;
}
// ---- <20><EFBFBD><E0AEAF><EFBFBD> <20><><><E1ABA5><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SCDEND()
{
$LODSB
IF(AL!=0){
$CMP AL,_END
$JNE SCDEND
illegaloperand();
$POP EAX; // <20><><20><> MapOperands
}
}
GETSCALING()
{
NextTok(); // <20><><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><E7A5AD> <20><><EFBFBD><EFBFBD><EFBFBD><E2A0A1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6A8A5><EFBFBD>
IF(tok==tk_number){
DoScale:
EA_SCALE=number; // Scale
EA_SIBFLAG=1; // <20>⬥⨬ <20><><EFBFBD><EFBFBD>稥 Sib <20> 32-<2D><><EFBFBD> EA
}
ELSE preerror("ASM: Illegal scaling value\n");
}
// ---- <20><><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><20> <20><><EFBFBD><EFBFBD><E0A0AD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E0A0AD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>樨)
GETOL1()
{
if(DSBYTE[ESI]!=0){ // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> JMP - <20><> <20><EFBFBD><E0AEA2>塞 ᮢ<><E1AEA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E0A0A7>
G4:
$LODSB
AH=AL&NOLBITS; // <20><EFBFBD><20><><20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
if(NOTZEROFLAG){// <20><><EFBFBD> <20><><EFBFBD>-⠪<> JMP...
DL=AL&OPBITS; // <20><><20><><EFBFBD> <> <20><><EFBFBD><EFBFBD><E0A0AD>
IF(DL!=SOO){ // <20> <20><><EFBFBD><EFBFBD><><E0A0A7><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD><><EFBFBD><E0A6A8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E0ACA0><EFBFBD> <20> <> <20><><EFBFBD><EFBFBD><E0A0AD>?
AL&=OLBITS; // <20><EFBFBD><EBA4A5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
IF(AL!=OL1){ // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>?
G3:
do{
$LODSB // <20><><EFBFBD><EFBFBD>ਬ ᫥<><E1ABA5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E8A0A1><EFBFBD><EFBFBD>
IF(AL==0)GOTO G4; // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
}while(AL!=_END); // <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><><E8A0A1><EFBFBD><EFBFBD>?
illegaloperand(); // <20><><EFBFBD> <20><><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><><E2A0AA> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$POP EAX;
$RET // <20><><20><> MapOperands
}
// <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E8A0A1><EFBFBD><EFBFBD>
G2:
AL=AH&TRANSBITS; // <20><EFBFBD><EBA4A5><EFBFBD><><E0A0A7><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD>
$CMP AL,_D
$JBE G5 // <20><><EFBFBD><EFBFBD> <20>.<2E>. ࠧ<><E0A0A7><EFBFBD><EFBFBD>: byte, word, dword
$CMP AL,_OW
$JNE J0
OPERANDSIZE=_W;
GOTO G40;
J0:
$CMP AL,_OD;
$JNE J1
OPERANDSIZE=_D;
GOTO G40;
J1:
$CMP AL,NB
$JB G90 // <20><><EFBFBD><EFBFBD> <20>.<2E>. ࠧ<><E0A0A7><EFBFBD><EFBFBD> WB,DW OR BW.
AL-=NB; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><><E4A8AA><EFBFBD><E0AEA2><EFBFBD><EFBFBD><EFBFBD><><E0A0A7>஢: NB->B,OW->W, AF->D
G90:
$CMP AL,OPERANDSIZE // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD> <20><><E0A0A7><EFBFBD> <20><><><E8A0A1><EFBFBD><EFBFBD><><E1AEA2><EFBFBD><EFBFBD>?
$JNE G3 // <20><><EFBFBD> - ᬮ<>ਬ ᫥<><E1ABA5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD>
GOTO G40; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E1AEA2><EFBFBD><EFBFBD> - <20><EFBFBD><E0AEA4><EFBFBD><EFBFBD><EFBFBD>
G5:
$CMP AL,OPERANDSIZE // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD> <20><><E0A0A7><EFBFBD> <20><><><E8A0A1><EFBFBD><EFBFBD><><E1AEA2><EFBFBD><EFBFBD>?
$JA G3 // <20><><EFBFBD> - ᬮ<>ਬ ᫥<><E1ABA5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD>
EBX=0; // WBIT/RANDFLAG=0
DL=AL;
AL=OPERANDSIZE;
IF(DL==_B)&&(AL!=_B)BL++;
// $CMP DL,_B // <20><><E8A0A1><EFBFBD><EFBFBD> byte?
// $JNE G20
// $CMP AL,_B // <20><><EFBFBD><EFBFBD> byte?
// $JE G20
// BL++; // W-<2D><><EFBFBD>=TRUE
//G20:
$CMP AL,_W // <20><><E8A0A1><EFBFBD><EFBFBD> word?
$JNE G30
$JA G30
BH++; // <20><><EFBFBD><EFBFBD> <20><>易⥫쭮 <20>.<2E>. word - <20><EFBFBD><E0A5A1><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> RAND
G30:
WBIT=BL;
RANDFLAG=BH; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E0ACA0><EFBFBD> <20> <20><><EFBFBD><EFBFBD><E4A8AA> <20> W-<2D><><EFBFBD><EFBFBD>
G40:
AH&=NTRANSBITS; // <20><><EFBFBD><E2A0A2> SOO <20><><EFBFBD><EFBFBD>
}
}
}
AL=AH; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⨬ SOO <20><><EFBFBD><EFBFBD>
}
// ---- <20><><EFBFBD><EFBFBD><EFBFBD>ઠ 蠡<><E8A0A1><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E0A0AD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GETOL2()
{
G7:
$LODSB // <20><><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD> <20><><><E8A0A1><EFBFBD><EFBFBD>
AH=AL;
AL&=OLBITS; // <20><EFBFBD><EBA4A5><EFBFBD> <20><><20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
$CMP AL,OL2 // <20><><20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD> = 2?
$JE G8 // <20><> - <20><><EFBFBD> <20><EFBFBD><E0AEA2><EFBFBD><EFBFBD>
G9:
$LODSB // <20><><EFBFBD><EFBFBD><EFBFBD><><E1ABA5><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD>
$OR AL,AL // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
$JZ G7 // <20><> - <20><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$CMP AL,_END // <20><><EFBFBD><EFBFBD><EFBFBD><><E8A0A1><EFBFBD><EFBFBD>?
$JNE G9 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> - <20><EFBFBD><E8A8A1>
toomuchoperands();
$POP EAX;
$RET // <20><><20><> MapOperands
G8:
AH&=NOLBITS; // <20><EFBFBD><20><><20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
AL=AH;
AL&=TRANSBITS; // <20><EFBFBD><EBA4A5><EFBFBD><><E0A0A7><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD>
$CMP AL,_D
$JBE G100 // <20><><EFBFBD><EFBFBD> <20>.<2E>. ࠧ<><E0A0A7><EFBFBD><EFBFBD>: byte, word, dword
G94:
$CMP AL,NB
$JB J0 //G95 // <20><><EFBFBD><EFBFBD> <20>.<2E>. ࠧ<><E0A0A7><EFBFBD><EFBFBD> WB,DW OR BW.
AL-=NB; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><><E4A8AA><EFBFBD><E0AEA2><EFBFBD><EFBFBD><EFBFBD><><E0A0A7>஢: NB->B,OW->W, AF->D
G95:
$CMP AL,OPERANDSIZE // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD> <20><><E0A0A7><EFBFBD> <20><><><E8A0A1><EFBFBD><EFBFBD><><E1AEA2><EFBFBD><EFBFBD>?
$JNE G9 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><><E1AEA2><EFBFBD><EFBFBD> - <20>饬 ᫥<><E1ABA5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$JMP G11 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E1AEA2><EFBFBD><EFBFBD> - <20><EFBFBD><E0AEA4><EFBFBD><EFBFBD><EFBFBD>
J0:
$CMP OPDESC[0],CO
$JNE J1
$CMP AL,WB;
$JNE J1
OPCONSTSIZE[0]=_W;
OPCONSTSIZE[1]=_B;
GOTO G11;
J1:
$CMP AL,_DW;
$JNE J2;
RANDFLAG=0;
OPCONSTSIZE[0]=_D;// OPCONSTSIZE[1]=_W;
GOTO G11;
J2:
$CMP AL,BW;
$JNE G95
OPCONSTSIZE[0]=_B;
OPCONSTSIZE[1]=_W;
GOTO G11;
G100:
$CMP OPERANDSIZE,_D
$JA NEAR G9 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD> > dword - <20><><><E1ABA5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$CMP OPERANDSIZE,AL
$JB NEAR G9 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><><E1AEA2><EFBFBD><EFBFBD> - <20>饬 ᫥<><E1ABA5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
EBX=0;
DL=AL;
AL=OPERANDSIZE;
$CMP DL,_B // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD> = byte?
$JNE G50
$CMP AL,_B // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD> = byte?
$JE G50
BL++; // W-<2D><><EFBFBD>=TRUE
G50:
$CMP AL,_W // <20><><E8A0A1><EFBFBD><EFBFBD> word?
$JNE G60
$JA G60
BH++; // <20><><EFBFBD><EFBFBD> <20><>易⥫쭮 <20>.<2E>. word - <20><EFBFBD><E0A5A1><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> RAND
G60:
WBIT=BL;
RANDFLAG=BH;
G11:
AH&=NTRANSBITS;
AL=AH; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⨬ SOO <20><><EFBFBD><EFBFBD>
}
// ---- <20><><EFBFBD><EFBFBD><EFBFBD>ઠ 蠡<><E8A0A1><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E0A0AD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GETOL3()
{
G12:
$LODSB
AH=AL;
AL&=OLBITS;
$CMP AL,OL3
$JE G13
G14:
$LODSB //TRY NEXT ENTRY.
$OR AL,AL
$JZ G12
$CMP AL,_END
$JNE G14
toomuchoperands();
$POP EAX;
$RET // <20><><20><> MapOperands
G13:
AH&=NOLBITS;
$CMP OPERANDSIZE,_D //DWORD ?
$JE G15
$CMP OPERANDSIZE,_W //WORD ?
$JE G16
preerror("ASM: This instruction required a WORD/DWORD operand\n");
$RET
G16:
RANDFLAG=1;
G15:
AL=AH&0xE0;
}
// ----
CREATE_EA()
{
EA_M=AL&7;
EA_X=3;
}
// ----
CREATE_R()
{
EA_R=AL&7;
}
// ---- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ModRM <20> Sib
GETMODRMBYTE()
{
DL=EALENGTH; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⢮ ॣ<><E0A5A3><EFBFBD><20> EA
$OR DL,DL // <20><><EFBFBD><><E0A5A3><EFBFBD><20> EA?
$JE NEAR C11 // <20><>
$TEST EADESC,_W+_D*8
$JE NEAR E1 // 8-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E0A5A3><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><E0A8AC><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$TEST EADESC,_W*8 // 16-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E0A5A3><EFBFBD><EFBFBD>?
$JNE NEAR E4 // 16-<2D><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><><E0A0A7><EFBFBD>
GETEADISPX();
$CMP DH,2
$JNZ X00
EAX=opDescInd;
OPCONSTSIZE[EAX]=_D; // <20><>易⥫쭮 32-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> disp
X00:
DL--; // 1 ॣ<><E0A5A3><EFBFBD><EFBFBD>?
$JNE N1 // <20><><EFBFBD>...
AL=EADESC&7;
$CMP EA_SIBFLAG,1 // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Sib <20> 32-<2D><><EFBFBD> EA
$JNE L2 // <20><><EFBFBD> Sib
EA_R2=5; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E0A5A3><EFBFBD><EFBFBD>
EA_M=4;
EA_I=AL;
EDX=opDescInd;
$CMP OPCONSTFLAG[EDX],1 // <20><EFBFBD><E1AFAE><EFBFBD>㥬 disp?
$JE L1
EAX=0;
OPCONSTFLAG[EDX]=1;
EDX<<=2;
OPCONST[EDX]=EAX; // disp=0 <20> EA
L1:
EDX=opDescInd;
OPCONSTSIZE[EDX]=_D;
EA_X=0; //EA_X=AL;
$RET
L2:
EA_M=AL;
$RET
N1:
EA_M=4; //2 REGISTERS USED.
EA_SIBFLAG=1;
AL=EADESC[1]>>3;
$CMP AL,_W
$JE E5 //ERROR: INDEX REGISTER ISN'T OF SIZE DWORD
AL=EADESC;
AH=EADESC[1];
EAX&=0x707;
$CMP AH,5 //CAN'T USE BP AS INDEX.
$JE E6
EA_R2=AL;
EA_I=AH;
$RET
E1:
preerror("ASM: You can't use byte registers in addresses\n");
$RET
E4:
preerror("ASM: 16-bit addressing mode not allowed\n");
$RET
E5:
preerror("ASM: You must use a 32-bit registers for scaling\n");
$RET
E6:
preerror("ASM: You can't use EBP as an index\n");
$RET
C11:
EA_X=0;
EA_M=5;
ECX=opDescInd;
AL=OPCONSTSIZE[ECX];
IF(AL==_B)OPCONSTSIZE[ECX]=_D;
ELSE IF(AL==_W)ADDRFLAG=1;
}
// ----
GETEADISPX()
{ //CREATE X NIBBLE OF DISPLACEMENT SIZE.
DH=0;
$PUSH ECX
ECX=opDescInd;
IF(OPCONSTFLAG[ECX]==1){
AL=OPCONSTSIZE[ECX];
DH=2; //(D)WORD DISPLACEMENT
IF(AL==_B)DH--; //SBYTE DISPLACEMENT
}
EA_X=DH;
$POP ECX
}
// ---- <20><><EFBFBD><EFBFBD><E6A8A0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><E1A5AC><EFBFBD><EFBFBD><EFBFBD>
INIT_LINE()
{
ECX=#opDescInd-#OPERANDSIZE;
AL=0;
EDI=#OPERANDSIZE;
$REP $STOSB;
AL=255;
OPERANDSIZE=AL;
SEGREGISTER=AL;
}
// ---- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A5A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E1A5A3><EFBFBD><EFBFBD><EFBFBD>
WRITEOVERRIDE()
{
EBX=OVERRIDE;
IF(BL!=0){
AL=OVERRIDETAB[EBX]-rES;
OP();
}
}
// ---- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E4A8AA><><E0A0A7><EFBFBD><E0ADAE><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD>
WRITERAND()
{
$PUSH EAX
IF(RANDFLAG==1){
AL=0x66;
OP();
}
$POP EAX
}
// ---- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E2A0AD>: CL=TYPE; EDI 㪠<><E3AAA0><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><E7A5AD>
WRITECONST()
{
IF(CL==_B)CL=1;
ELSE IF(CL==_W)CL=2;
ELSE IF(CL==_D)CL=4;
ELSE CL++;
loop(ECX){
AL=DSBYTE[EDI];
EDI++;
OP();
}
}
// ---- <20><><EFBFBD>⪠ Override
GETOVERRIDE()
{
IF(tok==tk_seg)&&(tok2==tk_colon){
IF(OVERRIDE==0){
OVERRIDE=number;
$STC // <20><><E1A5A3><EFBFBD><EFBFBD><E2ADAE><><E0A5A3><EFBFBD><EFBFBD><EFBFBD>
}
ELSE preerror("ASM: Double segment override");
NextTok();
NextTok(); // <20><EFBFBD><EFBFBD><E1AAA0> :
}
}
// ---- <20><><EFBFBD><EFBFBD><EFBFBD><E1ABA5><EFBFBD><><E0A0A7><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD>: _B,_W,_D,WB,_DW & RAND-FLAG. AL=SIZE
DEF_OPSIZE()
{
AH=OPERANDSIZE;
IF(AH==255){
OPERANDSIZE=AL; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
return;
}
IF(AH==AL)return; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E1AEA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
IF(AX==0X100){ // RW,RB ?
RANDFLAG=1;// OPERANDSIZE=WB;
return;
}
IF(AX==0X200){ // RD,RB ?
IF(ACTUALMNEMDESC==#PCOMMANDS3_){
// OPERANDSIZE=_D;
return;
}
OPERANDSIZE=WB;
return;
}
IF(AX==0X201){ //RD,RW
RANDFLAG=1;
OPERANDSIZE=_DW;
}
}
// ---- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E4A8AA> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
WRITEADDR()
{
$PUSH EAX
IF(ADDRFLAG==1){
AL=0x67;
OP();
}
$POP EAX
}
// ---- <20><><EFBFBD><E0A5A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E0A0A7><EFBFBD><E0ADAE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E2A0AD>
DefConstSize()
{ // <20><><EFBFBD><E0A5A4><EFBFBD><EFBFBD><><E0A0A7><EFBFBD><E0ADAE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E2A0AD>
EBX=opDescInd;
DL=_D;
IF(OPPOST[EBX]==0){
EBX=opDescInd<<2;
EAX=OPCONST[EBX];
DL=_B; // byte
IF(long EAX>=-128){ // -128
$CMP EAX,0XFF // 255
$JNG W2
}
DL++; // _W - word
IF(long EAX>=-32768){
$CMP EAX,0XFFFF // 65535
$JNG W2
}
DL++; // _D - dword
}
W2:
EBX=opDescInd;
OPCONSTSIZE[EBX]=DL;
OPCONSTFLAG[EBX]=1;
}
// ---- <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><E1A5AC><EFBFBD><EFBFBD><EFBFBD>
DoMnemonics()
{
opDescInd=0;
EADescInd=0;
INIT_LINE(); // <20><><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD>
IF(number<24){
IF(number<8)EBX=#PCOMMANDS1;
ELSE IF(number<12){
number-=8;
EBX=#PCOMMANDS2;
}
ELSE IF(number<20){
number-=12;
EBX=#PCOMMANDS3;
}
ELSE{
number-=20;
EBX=#PCOMMANDS4;
}
number+=DSBYTE[EBX];
PFLAG=number;
EBX++;
}
ELSE{
number-=24;
EBX=number<<2;
EBX=TAB_MNEMONICS[EBX];
IF(EBX>=#T_DAA)&&(EBX<#T_NOT){ // <20><EFBFBD><20><> <20><><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
ACTUALMNEMDESC=EBX;
IF(tok2==tk_semicolon)NextTok();
ESI=ACTUALMNEMDESC;
$JMP CreateCode;// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
}
}
ACTUALMNEMDESC=EBX; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E3AAA0><EFBFBD> <20><><>騩 蠡<><E8A0A1><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for(;;){ // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
prevTok=tok;
NextTok(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD>
FastSearch(#string,#St_Sizes);// <20><><EFBFBD><><E0A0A7><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD>?
IF(CARRYFLAG){ // <20><>: byte,word <20><><EFBFBD> dword
OPERANDSIZE=AL; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> _B,_W,_D
continue;
}
GETOVERRIDE(); // <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>樨 SEG:
ContLine: // <20><><20><><EFBFBD> <20><EFBFBD><E0AEA4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>⪨ ⥪<><EFBFBD>
IF(tok==tk_eof)||(tok==tk_semicolon){
EBX=opDescInd;
IF(OPDESC[EBX]==E){ // <20><><EFBFBD><20> EA?
DefConstSize();
GETMODRMBYTE(); // EOL - GENERATE MODRM OPCODE BYTE.
}
IF(prevTok!=tk_mnemonics){ // <20><20><><EFBFBD><EFBFBD><E0A0AD>
OPLENGTH++;
IF(OPERANDSIZE==255){
OPERANDSIZE=_D; // <20>ਭ㤨⥫쭮 <20><><EFBFBD><E2A0AD><EFBFBD><EFBFBD> dword
}
}
$JMP MapOperands
}
else IF(tok==tk_comma){
IF(opDescInd==3){
toomuchoperands();
break;
}
EBX=opDescInd;
IF(OPDESC[EBX]==E){ // <20><><EFBFBD><20> EA?
DefConstSize();
GETMODRMBYTE(); // EOL - GENERATE MODRM OPCODE BYTE.
}
opDescInd++;
OPLENGTH++;
}
else IF(tok==tk_openblock){
EBX=opDescInd;
OPDESC[EBX]=E; // <20>⬥⨬, <20><><EFBFBD><><EFBFBD> <20> EA <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
}
else IF(tok==tk_closeblock){ // ]
DefConstSize();
GETMODRMBYTE(); // EOL - GENERATE MODRM OPCODE BYTE.
}
else IF(tok==tk_minus){
IF(tok2 == tk_number){
NextTok();
number = -number;
$JMP ContLine; // <20><EFBFBD><E0AEA4><EFBFBD><EFBFBD><EFBFBD> docase <20><><EFBFBD> <20>롮ન ᫥<>.token
}
}
else IF(tok==tk_plus) continue;
else IF(tok==tk_mult){ // *
GETSCALING(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><20> Sib
}
else if(tok==tk_reg){ // <20><><EFBFBD>⪠ ॣ<><E0A5A3><EFBFBD><EFBFBD><EFBFBD>
G0:
EBX=opDescInd;
IF(OPDESC[EBX]==E){ // <20><><EFBFBD><20> EA?
IF(type==tk_byte){
preerror("ASM: No byte register in address\n");
return;
}
IF(EALENGTH<2){ // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⢮ ॣ<><E0A5A3><EFBFBD><20> EA < 2 ?
EALENGTH++; // <20>⬥⨬, <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><><E0A5A3><EFBFBD><EFBFBD> <20> EA
EBX=EADescInd;
EADESC[EBX]=number; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E0A5A3><EFBFBD><EFBFBD><EFBFBD>
EADescInd++;
}
ELSE{ // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><><E0A5A3><EFBFBD><20> EA
preerror("ASM: too much registers in combination\n");
return;
}
}
ELSE{
OPDATA[EBX]=number; // <20><><E0A5A3><EFBFBD><EFBFBD><EFBFBD>
OPDESC[EBX]=R;
AH=number&7;
EA_R=AH;
IF(opDescInd!=2){
AL>>=3;
DEF_OPSIZE();
}
}
}
else IF(tok==tk_number) { // <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><E2A0AD>
IF(tok2==tk_mult){
DoScale();
NextTok();
continue;
}
NUM:
EBX=opDescInd<<2;
OPCONST[EBX]+=number; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E2A0AD>
DefConstSize(); // <20><><EFBFBD><E0A5A4><EFBFBD><EFBFBD><><E0A0A7><EFBFBD><E0ADAE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><E2A0AD>
IF(OPDESC[EBX]!=E) // <20><><EFBFBD><EFBFBD><EFBFBD><E2A0AD> <20> EA?
OPDESC[EBX]=CO;
}
else IF(tok==tk_postnumber){
EBX=opDescInd;
OPPOST[EBX]=POST_DATA;
EBX<<=2;
OPPOSTREF[EBX]=treeptr;
ESI=treeptr;
DSDWORD[ESI+recpost]++;
GOTO NUM;
}
else IF(tok==tk_proc){
IF(post){
EBX=opDescInd;
OPPOST[EBX]=POST_CALL;
EBX<<=2;
OPPOSTREF[EBX]=treeptr;
ESI=treeptr;
DSDWORD[ESI+recpost]++;
}
$JMP NUM
}
else IF(tok==tk_locallabel){
EBX=opDescInd<<2;
OPPOSTREF[EBX]=localptr;
I2:
EBX=opDescInd;
$CMP ACTUALMNEMDESC,#T_JCXZ;
$JB I1
$CMP ACTUALMNEMDESC,#T_CALLFAR;
$JA I1
OPPOST[EBX]=POST_CALL;
$JMP NUM
I1:
OPPOST[EBX]=POST_DATA;
AL=_D;
DEF_OPSIZE();
$JMP PARSE_EA1
}
else IF(tok==tk_undefproc){
I0:
EBX=opDescInd<<2;
OPPOSTREF[EBX]=treeptr;
GOTO I2;
}
else IF(tok==tk_id){
tok = tk_undefproc;
post = 1;
number=0;
AddToTree(#string);
GOTO I0;
}
else IF(tok==tk_var){ // <20><><EFBFBD><EFBFBD><E6A8A0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> EA <20> <20><><EFBFBD><EFBFBD>⠭⮩: EA+disp
AL=type-tk_byte>>1; // AL=ࠧ<><E0A0A7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3A5AC><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD> (_B,_W,_D)
DEF_OPSIZE();
EBX=opDescInd;
IF(post){
EBX<<=2;
OPPOSTREF[EBX]=treeptr;
EBX=opDescInd;
OPPOST[EBX]=POST_DATA;
ESI=treeptr;
DSDWORD[ESI+recpost]++;
}
PARSE_EA1:
OPDESC[EBX]=E;
OPCONSTFLAG[EBX]=1; // <20>⬥⨬, <20><><EFBFBD><><EFBFBD> <20> EA <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
EBX<<=2;
OPCONST[EBX]+=number; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
}
else IF(tok==tk_seg){
EBX=opDescInd;
OPDATA[EBX]=number-rES; // <20><><E1A5A3><EFBFBD><EFBFBD><E2ADAE><><E0A5A3><EFBFBD><EFBFBD><EFBFBD>
SEGREGISTER=AL;
AL<<=3; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> XSM <20><><EFBFBD><EFBFBD>
EA_S=AL;
OPDESC[EBX]=_SR;
AL=_W;
DEF_OPSIZE();
}
else IF(tok==tk_param)||(tok==tk_local){
PARSE_PAR:
AL=type-tk_byte>>1;
DEF_OPSIZE();
EBX=opDescInd;
OPDESC[EBX]=E;
EBX<<=2; // <20>⬥⨬, <20><><EFBFBD><><EFBFBD> <20> EA <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
OPCONST[EBX]+=number; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
OPCONSTFLAG[EBX]=1;
number=rEBP;
$JMP G0;
}
else IF(tok==tk_controlreg){
EBX=opDescInd;
OPDESC[EBX]=SYSR;
SYSRNUM=number;
IF(AL==4)SYSRTYPE=_CR4;
ELSE{
SYSRTYPE=_CR;
SYSRCODE=0;
}
}
ELSE IF(tok==tk_debugreg){
EBX=opDescInd;
OPDESC[EBX]=SYSR;
SYSRNUM=number;
SYSRTYPE=_DR;
SYSRCODE=1;
}
ELSE IF(tok==tk_testreg){
EBX=opDescInd;
OPDESC[EBX]=SYSR;
SYSRNUM=number;
SYSRTYPE=_TR;
SYSRCODE=4;
}
ELSE preerror("ASM: Syntax error\n");
}
}
CreateScale()
{
IF(ADDRFLAG)return;
if(EA_SIBFLAG){ // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Sib <20> 32-<2D><><EFBFBD> EA
IF(EA_SCALE==0){ // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
EA_SCALING=0;
}
else IF(EA_SCALE==1)EA_SCALING=0;
else IF(EA_SCALE==2)EA_SCALING=0x40;
ELSE IF(EA_SCALE==4)EA_SCALING=0x80;
ELSE IF(EA_SCALE==8)EA_SCALING=0xC0;
ELSE{
EA_SCALING=0;
IF(EA_SCALE>255)OP(byte 0x69);
ELSE OP(byte 0x6B);
AL=EA_I<<3|EA_I|0xC0;
OP(byte AL);
IF(EA_SCALE>255)OUTDWORD(EA_SCALE);
ELSE OP(byte EA_SCALE);
}
}
}
// ---- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. ESI=ptr <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><E1A0AD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <> T_...)
CreateCode()
{
WRITEOVERRIDE();
CreateScale();
IF(ADDRFLAG==1){ //ADDR: PREFIX ?
OP(byte 0x67);
}
IF(RANDFLAG==1){ //RAND: PREFIX ?
OP(byte 0x66);
}
EDI=ESI;
IF(ACTUALMNEMDESC==#T_TEST)DBIT=0; //DON'T ADD ANYTHING IF TESTING
$SHL DBIT,1 //SHIFT D-BIT TO THE RIGHT POSITION.
NEXT_DESC_BYTE: // <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><E0A8AF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
EBX=0;
BL=DSBYTE[EDI];
EDI++;
NB3:
$CMP BL,X7M
$JA NC3
$CMP BL,X0M
$JB N24
AH=BL-X0M;
AL=EA_X<<3|AH<<3|EA_M;
OP();
GOTO NEXT_DESC_BYTE;
N24:
EBX<<=2;
EBX+=#Dsc_Jump;
$JMP NEAR DSDWORD[EBX]
NC3:
$CMP BL,_END
$JNE E42
$JMP CreateConstants // <20><><EFBFBD><EFBFBD><EFBFBD><><E8A0A1><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
E42:
preerror("Descriptor damaged\n");
return;
// OpCode - 1 <20><><EFBFBD><EFBFBD>
Dsc_O:
AL=DSBYTE[EDI]+WBIT+DBIT;
EDI++;
OP();
GOTO NEXT_DESC_BYTE;
// OpCode - 1 ᫮<><E1ABAE>
Dsc_OW:
AL=DSBYTE[EDI];
EDI++;
OP();
AL=DSBYTE[EDI]+WBIT+DBIT;
EDI++;
OP();
$JMP NEXT_DESC_BYTE
// OpCode - 1 <20><><EFBFBD><EFBFBD> <20><><E1ABA5><EFBFBD><20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 8-<2D><><EFBFBD> <20><><EFBFBD><E0AEAA>
Dsc_OS:
AL=DSBYTE[EDI];
EDI++;
OP();
// OpCode - 8-<2D><><EFBFBD> <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD>
Dsc_S:
S01:
CL=3;
EAX=0;
loop(CL){
AL=DSBYTE[EDI];
EDI++;
IF(AL=='X'){ //X CHAR
AL=EA_X;
}
ELSE IF(AL=='R')AL=EA_R;
ELSE IF(AL=='M')AL=EA_M;
ELSE IF(AL=='S')AL=SEGREGISTER;
ELSE IF(AL=='N')AL=SYSRNUM;
ELSE IF(AL=='P')AL=PFLAG;
ELSE AL-='0';
AH=AH<<3|AL;
}
AL=AH+DBIT+WBIT;
N15:
OP();
$JMP NEXT_DESC_BYTE
// OpCode - ModRM <20><><EFBFBD><EFBFBD>
Dsc_XRM:
AL=EA_X<<3|EA_R<<3|EA_M; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E0A5A3><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><E1A0AD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GOTO N15;
// OpCode - ModRM <20> P-䫠<><E4ABA0><EFBFBD> (<28><><EFBFBD><EFBFBD><E4ACA5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>樨)
Dsc_XPM:
AL=EA_X<<3|PFLAG<<3|EA_M;
GOTO N15;
// OpCode - ModRM <20><><E1A5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E0A5A3><EFBFBD>
Dsc_XSM:
AL=EA_X<<3|SEGREGISTER<<3|EA_M;
GOTO N15;
// JMP NEXT_DESC_BYTE
}
// ---- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>祭 -> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><><E8A0A1><EFBFBD><EFBFBD>
MapOperands()
{
// AL=0; WBIT=AL; DBIT=AL;
opDescInd=0;
ESI=ACTUALMNEMDESC; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><E0ACA0><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
AL=OPLENGTH; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
ECX=#OPDESC; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><E0ACA0><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
ECX=DSDWORD[ECX];
IF(ESI!=#T_MOV){ // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MOV?
IF(AL!=0){
$CMP AL,1
$JE NEAR ONEOP // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
$CMP AL,2
$JE NEAR TWOOPS // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD><EFBFBD>
$CMP AL,3
$JE NEAR THREEOPS // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD><EFBFBD>
toomuchoperands();
return;
}
// ---- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
do{
$LODSB
IF(AL==0)goto CreateCode; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
}while(AL!=_END);
preerror("ASM: Operand required\n");
return;
// ---- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MOV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
$PUSH EAX,ECX
WRITEOVERRIDE();
CreateScale();
$POP ECX,EAX
IF(AL!=2){ // 2 OPERANDS IN INSTRUCTION?
preerror("ASM: Two operands required\n");
return;
L2:
preerror("ASM: Not same size\n");
return;
}
L1:
BL=0;
AL=OPERANDSIZE;
IF(AL!=_D){
$CMP AL,_W
$JA L2
$JNE N4
RANDFLAG=1;
}
BL=1;
N4:
WBIT=BL; //STORE W-BIT
DL=0; //CLEAR D-BIT
WRITEADDR();
EBX=0;
BL=CL;
EBX=EBX<<2+#Jmp_Mov;
$JMP NEAR DSDWORD[EBX]
Mov_ERR:
preerror("ASM: a constant can't be used as a destination\n");
return;
Mov_R:
EBX=0;
BL=CH;
EBX=EBX<<2+#Jmp_Mov_R;
$JMP NEAR DSDWORD[EBX]
Mov_E:
EBX=0;
BL=CH;
EBX=EBX<<2+#Jmp_Mov_E;
$JMP NEAR DSDWORD[EBX]
Mov_R2R:
WRITERAND();
AL=OPDATA[1];
AH=OPDATA[0];
DL=DBIT;
$PUSH EAX
AL=0o210+WBIT;
$SHL DL,1
AL+=DL; //D-BIT
OP();
$POP EAX
AL=AL&7<<3;
AH&=7;
AL=AL|AH|0o300;
OP();
$JMP CreateConstants
Mov_R2E:
AL=OPDATA&7; //AL/AX/EAX ?
$OR AL,AL
$JNE N1
$CMP EA_M,6 //AR,[DW] POSSIBLE?
$JNE N1 //NO, ONLY AR,[EA]
$CMP ADDRFLAG,0 //32BIT-EA ?
$JE N1 //NO, TRY ANOTHER...
WRITERAND();
AL=0o240+WBIT; //INSTRUCTION FOUND.
OP();
$JMP CreateConstants
Mov_E2R:
D1:
AL=OPDATA[1]&7; //[DW],AR POSSIBLE?
$OR AL,AL
$JNE Y1
$CMP ADDRFLAG,0 //32BIT EA ?
$JNE Y1 //YES, RAVE ON...
$CMP EA_M,6
$JNE Y1
WRITERAND();
AL=0o242+WBIT; //INSTRUCTION FOUND.
OP();
$JMP CreateConstants
N1:
DL=2; //SET D-BIT
Y1:
DL+=0o210;
WRITERAND();
AL=DL;
DL=0;
AL+=WBIT;
OP();
AL=EA_X<<3|EA_R<<3|EA_M;
OP();
$JMP CreateConstants
E1:
preerror("ASM: Not same size\n");
return;
//EA,CONSTANT ?
Mov_E2C:
OPCONSTSIZE[1]=OPERANDSIZE;
$CMP AL,_D
$JA E1
$JE X1
$CMP AL,_W
$JNE X1
AL=0x66;
OP();
X1:
AL=0o306+WBIT;
OP();
AL=EA_X<<6|EA_M;
OP();
$JMP CreateConstants
Mov_R2C:
OPCONSTSIZE[1]=OPERANDSIZE;
$CMP OPERANDSIZE,_B
$JNE N2
AL=OPDATA&7|0o260;
OP();
$JMP CreateConstants
N2:
$CMP OPERANDSIZE,_D //BYTE, WORD OR DWORD?
$JA NEAR E1 // Not same size
IF(OPERANDSIZE==_W){
AL=0x66;
OP();
}
AL=OPDATA&7|0o270;
OP();
$JMP CreateConstants
E21:
preerror("ASM: Word required\n");
return; //SEGMENT REGISTER IS ALWAYS WORD.
Mov_S:
AL=0;
$CMP CX,_SR*256+E // mov EA,segreg
$JE O1
$CMP CX,_SR*256+R // mov segreg,reg
$JE O2
$CMP CX,R*256+_SR // mov reg,segreg
$JE O3
$CMP CX,E*256+_SR // mov segreg,EA
$JNE NEAR N12
AL=2; //SET D-BIT
O1:
$CMP OPERANDSIZE,_W
$JNE E21
AL+=0o214;
OP();
AL=EA_X<<6|EA_S|EA_M;
OP();
$JMP CreateConstants
O2:
$CMP OPERANDSIZE,_W
$JNE E21
AL=0o214;
OP();
AL=EA_S|0o300|EA_R; //CREATE XSM BYTE
OP();
$STC
$RET
O3:
$CMP OPERANDSIZE,_W
$JNE NEAR E21
AL=0o216;
OP();
AL=EA_S|0o300|EA_R;
OP();
$STC
$RET
E31:
preerror("ASM: CR1 only readable\n");
$RET
E32:
preerror("ASM: SysR must be dword\n");
$RET
Mov_SYSR:
N12:
AH=0o40;
$CMP CX,SYSR*256+R
$JE O11
$CMP CX,R*256+SYSR
$JNE N22 //ERROR: ILLEGAL OPERANDS
AH=0o42;
$CMP SYSRTYPE,_CR //CR1 REGISTER USED?
$JNE O11
$CMP SYSRNUM,1
$JE E31 //YES, ONLY READ FROM IT.
O11:
AH+=SYSRCODE;
$CMP OPERANDSIZE,_D //SYSTEM REGISTERS ARE ALWAYS DWORD.
$JNE E32
AL=0o17;
OP();
$CMP SYSRTYPE,_CR4 //EXCEPTION: CR4
$JE N22
AL=AH;
OP();
AL=SYSRNUM<<3|0o300|EA_R; //CREATE 3NR OPCODE
OP();
$STC
$RET
N22:
$CMP CX,SYSR*256+R
$JNE N32
AL=0x22;
OP();
GOTO L11;
N32:
AL=0x20;
OP();
L11:
AL=0o340|EA_R;
OP();
$STC
$RET
// ---- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD>
ONEOP:
EBX=CL<<2+#Jmp_Op1;
$JMP NEAR DSDWORD[EBX]
Op1ERR:
preerror("ASM: only use system registers within MOV instruction\n");
$RET
// RX
L31:
SCDEND();
Op1R:
GETOL1(); //GET FIRST GENERATION INFO.
$CMP AL,SOR //SINGLE OPERAND/REGISTER ?
$JNE X23
$JMP CreateCode
X23:
$CMP AL,SOE //CONVERT REGISTER INTO EFFECTIVE ADDRESS?
$JNE L31
C2:
EA_X=3;
AL=EA_R;
EA_M=AL;
$JMP CreateCode
// EA
L41:
SCDEND();
Op1E:
GETOL1();
$CMP AL,SOE //SINGLE OPERAND/EFFECTIVE ADDRESS ?
$JNE X24;
$JMP CreateCode
X24:
$CMP AL,SOM //SINGLE OPERAND/MEMORY POINTER ?
$JNE L41
$CMP EA_X,0
$JNE L41
$CMP EA_M,6 //[WORD CONSTANT]?
$JNE L41
C11:
$JMP CreateCode
// CO
L51:
SCDEND();
Op1C:
GETOL1();
$OR AL,AL //JUMP INSTRUCTION?
$JNE NEAR N13
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>⪠ call&jmp
ECX=OPCONST[0]-OptImageBase-OptBaseOfCode-outptr+output; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><E2ADAE>⥫쭮<E2A5AB><ECADAE> ᬥ饭<E1ACA5><E9A5AD>
$LODSB // <20><><EFBFBD><EFBFBD>稬 short <20><><EFBFBD> near
$CMP AL,_JB // short?
$JNE N14
ECX-=2;
$CMP ECX,0xFFFFFF80
$JL L10
$CMP ECX,0x7F
$JG L10
OPCONSTSIZE[0]=_B;
H1:
OPCONST[0]=ECX;
$JMP CreateCode
N14:
EAX=0;
$LODSB // <20><><EFBFBD><EFBFBD><E0A0A2> <20><><><E0A0A7><EFBFBD> call <20><><EFBFBD> jmp
ECX-=EAX;
OPCONSTSIZE[0]=_D;
GOTO H1;
L10:
$CMP ACTUALMNEMDESC,#T_JCXZ
$JB L51
$CMP ACTUALMNEMDESC,#T_LOOP
$JA NEAR L51
preerror("ASM: Jump range too long\n");
$RET
N13:
$CMP AL,SO3 //CONSTANT VALUE 3 ?
$JNE N23
$CMP OPCONST[0],3
$JNE NEAR L51
OPCONSTFLAG[0]=0; //YES, AVOID CONSTANT GENERATION.
$JMP CreateCode
N23:
$CMP AL,SOC //SINGLE OPERAND/CONSTANT?
$JNE X25
OPCONSTSIZE[0]=OPERANDSIZE;
$JMP CreateCode
X25:
$CMP AL,SOO_CC //SINGLE OPERAND/SIGNED BYTE ?
$JNE NEAR L51
IF(OPPOST[0])$JMP L51
$CMP OPCONST[0],0x7F
$JG NEAR L51
$CMP OPCONST[0],0xFFFFFF80
$JL NEAR L51
OPCONSTSIZE[0]=_B;
$JMP CreateCode
// SR
L61:
SCDEND();
Op1S:
GETOL1();
$CMP AL,SOS //SINGLE OPERAND/SEGMENT REGISTER?
$JNE L61
$JMP CreateCode
// AF
L71:
SCDEND();
Op1AF:
GETOL1();
$CMP AL,SOO_AF
$JNE L71
$JMP CreateCode
// ---- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD><EFBFBD><EFBFBD>
TWOOPS:
EBX=CL<<2+#Jmp_Op2;
$JMP NEAR DSDWORD[EBX] // <20><><EFBFBD><EFBFBD><20><> <> <20><><EFBFBD><E0A2AE> <20><><EFBFBD><EFBFBD><E0A0AD>
//Op2ERRC:
// preerror("ASM: A constant can't be used as a destination\n");
// return;
Op2ERRS:
preerror("ASM: segment register can only be used within a MOV or PUSH\n");
return;
Op2ERRSYS:
preerror("ASM: only use system registers within MOV instruction\n");
return;
Op2ERRAF:
preerror("Absolute FAR addresses can only be used for jumps\n");
return;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20> 2-<2D><><EFBFBD><EFBFBD><E0A0AD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>樨 - ॣ<><E0A5A3><EFBFBD><EFBFBD>
Op2R:
EBX=0;
BL=CH;
EBX=EBX<<2+#Jmp_Op2R;
$JMP NEAR DSDWORD[EBX] // <20><><EFBFBD><EFBFBD><20><> <> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20> 2-<2D><><EFBFBD><EFBFBD><E0A0AD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>樨 - EA
Op2E:
EBX=0;
BL=CH;
EBX=EBX<<2+#Jmp_Op2E;
$JMP NEAR DSDWORD[EBX] // <20><><EFBFBD><EFBFBD><20><> <> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E0A0AD>
// mnem EA,RX
L81:
SCDEND();
OpE2R:
GETOL2(); // <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><><E8A0A1><EFBFBD><EFBFBD>
$CMP AL,DER //EA & R + D-BIT ?
$JE C21
X26:
$CMP AL,ERO //'ERO' ORDER ?
$JE C21
$CMP AL,EAO //EA, ?
$JNE L81 // <20><> <20><EFBFBD><E0AEAF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD>
$CMP OPDATA[1],rCL //CL REGISTER USED??
$JNE L81 // <20><> <20><EFBFBD><E0AEAF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD>
$CMP DSBYTE[ESI+1],rCL //CL IN GENERATION INFO?
$JNE L81 // <20><> <20><EFBFBD><E0AEAF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD>
// CMP OPERANDSIZE,_B //YES, CHECK SIZE.
// JNE L81 // <20><> <20><EFBFBD><E0AEAF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD>
ESI++;
ESI++;
C21:
$JMP CreateCode
L91:
SCDEND();
OpR2E:
GETOL2();
$CMP AL,DER //DER ?
$JNE N43
DBIT=1; //(DIRECTION BIT)
$JMP CreateCode
N43:
$CMP AL,REO //REO ?
$JNE L91;
$JMP CreateCode
//RX,RX ?
W2:
ESI++;
GOTO W1;
LA1:
SCDEND();
OpR2R:
$CMP DSBYTE[ESI],_B+OL2+EAO // <20><><EFBFBD><EFBFBD>+2<><32>+EAold?
$JE W2 //EAO FOUND, R+R COMBINATION NOT PERMITTED.
GETOL2(); // <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E8A0A1><EFBFBD><EFBFBD>
$CMP AL,DER // EA,reg <20><><EFBFBD> reg,EA <20> D/W-<2D><>⮬?
$JNE N53
LB2:
AL=OPDATA[0]; // <20><EFBFBD>ࠧ㥬 ॣ<><E0A5A3><EFBFBD><EFBFBD> <20> EA
CREATE_EA();
AL=OPDATA[1]; // <20><><EFBFBD><20><><EFBFBD><EFBFBD>
CREATE_R();
$JMP CreateCode
N53:
$CMP AL,ERO
$JE LB2
$CMP AL,REO
$JNE N63
AL=OPDATA[1]; //RX,EP
CREATE_EA();
AL=OPDATA[0];
CREATE_R();
$JMP CreateCode
N63:
$CMP AL,EAO
$JNE LA1 // <20><> <20><EFBFBD><E0AEAF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD>
W1:
ECX=2; //COMPARE 2 OPERANDS.
opDescInd=0;
LX2:
$LODSB // <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><E8A0A1><EFBFBD><EFBFBD>
$CMP AL,255 //1ST OPERAND OK.
$JE L022
$CMP AL,AR //AL/AX/EAX?
$JE OL2X_AR
$CMP AL,rDX //DX?
$JE OL2X_DX
$CMP AL,rCL
$JE OL2X_CL
GOTO LA1; // <20><> <20><EFBFBD><E0AEAF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD>
OL2X_AR:
EBX=opDescInd;
AH=OPDATA[EBX]&7; // <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$JNZ NEAR LA1 // <20><> <20><EFBFBD><E0AEAF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD>
L022:
opDescInd++;
$LOOP LX2
GOTO L23;
OL2X_DX:
EBX=opDescInd;
$CMP OPDATA[EBX],0o12
$JNE NEAR LA1 // <20><> <20><EFBFBD><E0AEAF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><E8A0A1><EFBFBD><EFBFBD>
opDescInd++;
$LOOP LX2
GOTO L23;
OL2X_CL:
EBX=opDescInd;
$CMP OPDATA[EBX],rCL //CL
$JNE NEAR LC1
opDescInd++;
$LOOP LX2
$TEST OPDATA[0],8+16 //1ST REGISTER WORD/DWORD?
$JZ L23
WBIT=1; //YES, SET W-BIT.
L23:
AL=OPDATA[0];
CREATE_EA();
$JMP CreateCode
//EA,CONSTANT ? //EA,CONST?
LB1:
SCDEND();
OpE2C:
GETOL2();
opDescInd=1;
$CMP AL,ECO
$JNE N73
OPCONSTSIZE[1]=OPERANDSIZE;
$JMP CreateCode
N73:
$CMP AL,EAO
$JNE N83
$CMP OPERANDSIZE,_B
$JNE N83
$CMP DSBYTE[ESI],_1
$JNE N83
$CMP OPCONST[4],1
$JNE N83
OPCONSTFLAG[1]=0;
ESI++;
$JMP CreateCode
N83:
$CMP AL,ECCO //EA/SIGNED BYTE ?
$JNE LB1
$CMP OPCONST[4],0xFFFFFF80
$JL LB1
$CMP OPCONST[4],0x7F
$JG NEAR LB1
OPERANDSIZE=_B; //OMIT A SINGLE BYTE ON GENERATION.
$JMP CreateCode
// mnem reg,const
LC1:
SCDEND();
OpR2C:
GETOL2();
opDescInd=1;
$CMP AL,RCO;
$JNE Q1
A0:
OPCONSTSIZE[1]=OPERANDSIZE;
$JMP CreateCode // reg,const
Q1:
$CMP AL,ECO;
$JNE L110
A1:
AL=EA_R;
CREATE_EA();
GOTO A0;
L110:
$CMP AL,EAO;
$JE N93
$CMP AL,ECCO;
$JNE LC1 //SIGNED BYTE CONST ?
$CMP OPCONST[4],0xFFFFFF80;
$JL LC1
$CMP OPCONST[4],0x7F;
$JG LC1
OPERANDSIZE=_B;
OPCONSTSIZE[1]=_B;
GOTO A1; //CONVERT REGISTER TO EFFECTIVE ADDRESS AND GENERATE OPCODE.
N93:
ECX=2; //COMPARE 2 OPERAND.
B2:
$LODSB;
$CMP AL,255;
$JE L122
$CMP AL,AR;
$JE OL2_AR //AL/AX/EAX?
$CMP AL,CO;
$JE OL2_CO //CONSTANT?
$CMP AL,rDX;
$JE OL2_DX //DX?
$CMP AL,_1;
$JE OL2_1 //CONSTANT VALUE 1?
$JMP LC1
OL2_AR:
AH=OPDATA[0]&7;
$JNZ NEAR LC1
L122:
$LOOP B2;
$JMP CreateCode
OL2_CO:
$CMP OPDESC[1],CO;
$JNE NEAR LC1
OPCONSTSIZE[1]=OPERANDSIZE;
GOTO L122;
OL2_DX:
$CMP OPDATA[0],0o12;
$JE L122;
$JMP LC1
OL2_1:
$CMP OPCONSTSIZE[1],_B;
$JNE NEAR LC1
$CMP OPCONST[4],1;
$JNE NEAR LC1
OPCONSTFLAG[1]=0;
$JMP A1
LD1:
SCDEND();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20> 2-<2D><><EFBFBD><EFBFBD><E0A0AD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>樨 - <20><><EFBFBD><EFBFBD><EFBFBD><E2A0AD>
Op2C:
GETOL2();
$CMP AL,EAO
$JNE LD1
ECX=2; //COMPARE 2 OPERANDS.
opDescInd=0;
B12:
$LODSB
$CMP AL,255
$JE L222
$CMP AL,AR //AL/AX/EAX
$JE XOL2_AR
$CMP AL,CO
$JE XOL2_CO
$CMP AL,rDX //DX
$JE XOL2_DX
$CMP AL,_1
$JE XOL2_1
GOTO LD1;
XOL2_AR:
EBX=opDescInd;
AH=OPDATA[EBX]&7;
$JNZ N21
L222:
opDescInd++;
$LOOP B12
$JMP CreateCode
N21:
GOTO LD1;
XOL2_CO:
EBX=opDescInd;
$CMP OPDESC[EBX],CO
$JNE LD1
opDescInd++;
$LOOP B12
$JMP CreateCode
XOL2_DX:
EBX=opDescInd;
$CMP OPDATA[EBX],0o12
$JNE NEAR LD1
opDescInd++;
$LOOP B12
$JMP CreateCode
XOL2_1:
EDX=opDescInd;
$CMP OPCONSTSIZE[EDX],_B
$JNE NEAR LD1
EDX<<=2;
$CMP OPCONST[EDX],1
$JNE NEAR LD1
EDX=opDescInd;
OPCONSTFLAG[EDX]=0;
AL=EA_R;
CREATE_EA();
$JMP CreateCode
// <20><><EFBFBD><EFBFBD><EFBFBD><E0A0AD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LE1:
SCDEND();
THREEOPS:
D11:
GETOL3();
$CMP AL,ERO
$JNE N42
$CMP CX,R*256+E
$JE O21
$CMP CX,R*256+R
$JNE LE1
AL=OPDATA[0];
CREATE_EA();
AL=OPDATA[1];
CREATE_R();
GOTO O21;
N42:
$CMP AL,REO
$JNE N52 //ERROR: INVALID OPERANDS.
$CMP CX,E*256+R
$JE O21
$CMP CX,R*256+R
$JNE LE1
AL=OPDATA[1];
CREATE_EA();
AL=OPDATA[0];
CREATE_R();
O21:
BL=AH&TRANSBITS;
$CMP OPCONSTFLAG[2],1
$JNE NEAR NA3
$CMP BL,CC3
$JNE N52
$CMP OPCONST[8],0xFFFFFF80
$JL NEAR LE1
$CMP OPCONST[8],0x7F
$JG NEAR LE1
OPCONSTSIZE[2]=_B;
$JMP CreateCode
N52:
$CMP BL,CB3
$JNE N62
$CMP OPCONST[8],0xFF
$JA NEAR LE1
OPCONSTSIZE[2]=_B;
$JMP CreateCode
N62:
$CMP BL,CW3
$JNE NA3
$CMP OPCONST[8],0xFFFFFFFF
$JA NEAR LE1
$CMP RANDFLAG,1
$JNE NA2
OPCONSTSIZE[2]=_W;
$JMP CreateCode
NA2:
OPCONSTSIZE[2]=_D;
NA_2:
$JMP CreateCode
NA3:
$CMP BL,CL3
$JNE NEAR LE1
$CMP OPDESC[2],R
$JNE NEAR LE1
$CMP OPDATA[2],rCL
$JE NA_2
illegaloperand();
}
CreateConstants()
{
$CMP EA_SIBFLAG,1 // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Sib <20> 32-<2D><><EFBFBD> EA
$JNE L3 // Sib <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$CMP ADDRFLAG,1
$JE L3 //NO, NORMAL XRM
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SIB - <20><><EFBFBD><EFBFBD><EFBFBD>
AL=EA_I<<3|EA_R2|EA_SCALING;
OP();
L3:
$CMP OPCONSTFLAG[0],1
$JNE NEAR N1
IF(OPPOST[0])SetPost(OPPOSTREF[0],OPPOST[0]);
ECX=OPCONSTSIZE[0];
EDI=#OPCONST; // <20><><EFBFBD><EFBFBD><E7A5AD> disp <20> EA
WRITECONST();
N1:
$CMP OPCONSTFLAG[1],1
$JNE NEAR N41
ECX=OPCONSTSIZE[1];
$CMP CL,AF //ABSOLUTE FAR ?
$JNE D21
EDI=#OPCONST+4; //YES, CREATE ADDRESS.
CL=_W; //(32 BIT)
$CMP ADDRFLAG,1
$JNE D2
ECX=_D; //(48 BIT)
D2:
WRITECONST();
EDX+=output;
EBX=EDX>>4;
$AND EDX,15
$PUSH EBX,EDX
$POP EDX //???
EAX=opDescInd;
DSDWORD[EAX]=EDX;
ECX=_W;
/* AFSEG <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><E0A5A4><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><EFBFBD><><E0A0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
EDI=#AFSEG; //(SEGMENT/SELECTOR) */
WRITECONST();
$STC
$RET
D21:
IF(OPPOST[1])SetPost(OPPOSTREF[4],OPPOST[1]);
EDI=#OPCONST+4;
WRITECONST();
N41:
IF(OPCONSTFLAG[2]==1){
ECX=OPCONSTSIZE[2];
EDI=#OPCONST+8;
WRITECONST();
}
}
// ----
illegaloperand()
{
preerror("ASM: Illegal operand\n");
}
// ----
toomuchoperands()
{
preerror("ASM: Illegal number of operands\n");
}
// JUMP TABLES
dword Jmp_Mov={#Mov_R,#Mov_E,#Mov_ERR,#Mov_S,
#Mov_SYSR,#Mov_SYSR,#Mov_SYSR,#Mov_SYSR,#Mov_SYSR,#Mov_SYSR};
dword Jmp_Mov_R={#Mov_R2R,#Mov_R2E,#Mov_R2C,#Mov_S,
#Mov_SYSR,#Mov_SYSR,#Mov_SYSR,#Mov_SYSR,#Mov_SYSR,#Mov_SYSR};
dword Jmp_Mov_E={#Mov_E2R,#Mov_ERR,#Mov_E2C,#Mov_S,
#Mov_ERR,#Mov_ERR,#Mov_ERR,#Mov_ERR,#Mov_ERR,#Mov_ERR};
dword Jmp_Op1={#Op1R,#Op1E,#Op1C,#Op1S,
#Op1ERR,#Op1ERR,#Op1ERR,#Op1ERR,#Op1ERR,#Op1AF};
dword Jmp_Op2={#Op2R,#Op2E,#Op2C,#Op2ERRS,
#Op2ERRSYS,#Op2ERRSYS,#Op2ERRSYS,#Op2ERRSYS,#Op2ERRSYS,#Op2ERRAF};
dword Jmp_Op2R={#OpR2R,#OpR2E,#OpR2C,#Op2ERRS,
#Op2ERRSYS,#Op2ERRSYS,#Op2ERRSYS,#Op2ERRSYS,#Op2ERRSYS,#Op2ERRAF};
dword Jmp_Op2E={#OpE2R,0,#OpE2C,#Op2ERRS,
#Op2ERRSYS,#Op2ERRSYS,#Op2ERRSYS,#Op2ERRSYS,#Op2ERRSYS,#Op2ERRAF};
//dword TC_JMP={#T_JMPSHORT,#T_JMPNEAR,#T_JMPFAR};
//dword TC_CALL={0,#T_CALL,#T_CALLFAR};
//dword TC_J={#T_J,#T_JN,1};
dword Dsc_Jump={#CreateConstants,#Dsc_O,#Dsc_OW,#Dsc_OS,#Dsc_S,#Dsc_XRM,#Dsc_XPM,#Dsc_XSM};