forked from KolibriOS/kolibrios
02b76505a6
git-svn-id: svn://kolibrios.org@1846 a494cfbc-eb01-0410-851d-a64ba20cac60
1719 lines
35 KiB
Plaintext
1719 lines
35 KiB
Plaintext
dword ACTUALMNEMDESC; // “ª § â¥«ì ®¯¨á ¨¥ ⥪ã饩 ¬¥¬®¨ª¨
|
||
byte ACTUALMNEMONIC; // Š®¤ ⥪ã饩 ¬¥¬®¨ª¨
|
||
byte OPERANDSIZE; // <20> §¬¥à ®¯¥à ¤ (B,W,D,BW,WB,DW)
|
||
byte OPDESC[3]; // ’¨¯ë ®¯¥à ¤®¢ (R,E,D,CC,SR,TR,DR,CR)
|
||
byte OPDATA[3]; // ˆä®à¬ æ¨ï ¯® ®¯¥à ¤ã (RG,CO,EA)
|
||
dword OPCONST[3]; // ‡ 票¥ ª®áâ âë ¢ ®¯¥à ¤¥
|
||
byte OPCONSTFLAG[3]; // <20> «¨ç¨¥ ª®áâ âë ¢ ®¯¥à ¤¥
|
||
byte OPCONSTSIZE[3]; // <20> §¬¥à®áâì ª®áâ âë ¢ ®¯¥à ¤¥
|
||
byte OPPOST[3];
|
||
dword OPPOSTREF[3];
|
||
byte PFLAG; // ‡ 票¥ P-ä« £ (®¬¥à ª« áá ).
|
||
byte RANDFLAG; // TRUE: RAND: âॡã¥âáï ¯à¥ä¨ªá 0x66
|
||
byte ADDRFLAG; // TRUE: ADDR: âॡã¥âáï ¯à¥ä¨ªá 0x67
|
||
byte WBIT; // <20>¨â WORD ¢ OPCODE
|
||
byte DBIT; // <20>¨â DIRECTION ¢ OPCODE
|
||
byte OPLENGTH; // Š®«¨ç¥á⢮ ®¯¥à ¤®¢ ¢ ⥪ã饩 ¨áâàãªæ¨¨
|
||
byte EA_M; // <20> ©â 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; // Š®«¨ç¥á⢮ ॣ¨áâ஢ ¢ EA
|
||
byte EA_SIBFLAG; // ”« £ «¨ç¨ï Sib ¢ 32-¡¨â®¬ EA
|
||
byte EA_SCALING; // ˆ¤¥ªá ¢ Sib
|
||
dword EA_SCALE; // ‡ 票¥ ¤«ï Scale ¢ Sib
|
||
dword EADescInd; // ˆ¤¥ªá ¢ 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;
|
||
// ----- €áᥬ¡«¨à®¢ ¨¥ áâப¨
|
||
|
||
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; //§ ¯®¬¨âì ¯®§¨æ¨î à §¡®à
|
||
$PUSH linenum2,inptr2,number,tok2,tok,input,inptr,currmod,linenumber,
|
||
endoffile,displaytokerrors,type;
|
||
lstrcpyA(#s,#string);
|
||
lstrcpyA(#s2,#string2);
|
||
input=#source; //à §¡¨à ¥¬ ®¢ãî áâபã
|
||
inptr = input;
|
||
inptr2=input;
|
||
endoffile=0; // <20> ç «¥ ä ©«
|
||
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); //¢®áâ ®¢¨âì
|
||
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();
|
||
}
|
||
|
||
// ---- “áâ ®¢ª áá뫪¨ ¯®ª ¥®¡ê¥ë© ¨¤¥â¨ä¨ª â®à
|
||
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>யã᪠¤® á«¥¤ãî饩 § ¯¨á¨ ¢ è ¡«®¥ ¨áâàãªæ¨¨
|
||
SCDEND()
|
||
{
|
||
$LODSB
|
||
IF(AL!=0){
|
||
$CMP AL,_END
|
||
$JNE SCDEND
|
||
illegaloperand();
|
||
$POP EAX; // ‚ë室 ¨§ MapOperands
|
||
}
|
||
}
|
||
|
||
GETSCALING()
|
||
{
|
||
NextTok(); // <20>®«ã稬 § 票¥ ¬ áèâ ¡®£® ª®íää¨æ¨¥â
|
||
IF(tok==tk_number){
|
||
DoScale:
|
||
EA_SCALE=number; // Scale
|
||
EA_SIBFLAG=1; // Žâ¬¥â¨¬ «¨ç¨¥ Sib ¢ 32-¡¨â®¬ EA
|
||
}
|
||
ELSE preerror("ASM: Illegal scaling value\n");
|
||
}
|
||
|
||
// ---- <20>®¨áª ¢ è ¡«®¥ ¯®¤å®¤ï饩 ª ®¯¥à ¤ã § ¯¨á¨ (¤«ï ®¤®®¯¥à ¤®© ¨áâàãªæ¨¨)
|
||
GETOL1()
|
||
{
|
||
if(DSBYTE[ESI]!=0){ // ˆáâàãªæ¨ï JMP - ¥ ¯à®¢¥à塞 ᮢ¯ ¤¥¨¥ à §¬¥à®¢
|
||
G4:
|
||
$LODSB
|
||
AH=AL&NOLBITS; // ˆáª«î稬 ç¨á«® ®¯¥à ¤®¢
|
||
if(NOTZEROFLAG){// <20>â® ¢á¥-â ª¨ JMP...
|
||
DL=AL&OPBITS; // Œ ᪠¤«ï ⨯ ®¯¥à ¤
|
||
IF(DL!=SOO){ // ‚ ¯®«¥ à §¬¥à ®¯¥à ¤ ᮤ¥à¦¨âáï ¨ä®à¬ æ¨ï ® ⨯¥ ®¯¥à ¤ ?
|
||
AL&=OLBITS; // ‚뤥«¨¬ ª®«¨ç¥á⢮ ®¯¥à ¤®¢
|
||
IF(AL!=OL1){ // ˜ ¡«® ¤«ï ¨áâàãªæ¨¨ á ®¤¨¬ ®¯¥à ¤®¬?
|
||
G3:
|
||
do{
|
||
$LODSB // <20>à®á¬®âਬ á«¥¤ãîéãî § ¯¨áì è ¡«®
|
||
IF(AL==0)GOTO G4; // Š®¥æ § ¯¨á¨?
|
||
}while(AL!=_END); // <20>â® ª®¥æ è ¡«® ?
|
||
illegaloperand(); // <20>¥â ¯®¤å®¤ï饩 § ¯¨á¨ ¤«ï â ª®© ¬¥¬®¨ª¨
|
||
$POP EAX;
|
||
$RET // ‚ë室 ¨§ MapOperands
|
||
}
|
||
// Ž¡à ¡®âª § ¯¨á¨ è ¡«®
|
||
G2:
|
||
AL=AH&TRANSBITS; // ‚뤥«¨¬ à §¬¥à ®¯¥à ¤
|
||
$CMP AL,_D
|
||
$JBE G5 // Ž¯¥à ¤ ¬.¡. à §¬¥à : 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 // Ž¯¥à ¤ ¬.¡. à §¬¥à WB,DW OR BW.
|
||
AL-=NB; // <20>¥à¥áç¨â ¥¬ ¤«ï 䨪á¨à®¢ ëå à §¬¥à®¢: NB->B,OW->W, AF->D
|
||
G90:
|
||
$CMP AL,OPERANDSIZE // <20> §¬¥à ®¯¥à ¤ ¨ à §¬¥à ¨§ è ¡«® ᮢ¯ «¨?
|
||
$JNE G3 // <20>¥â - ᬮâਬ á«¥¤ãîéãî § ¯¨áì ¢ è ¡«®¥
|
||
GOTO G40; // <20> §¬¥àë ᮢ¯ «¨ - ¯à®¤®«¦¨¬
|
||
G5:
|
||
$CMP AL,OPERANDSIZE // <20> §¬¥à ®¯¥à ¤ ¨ à §¬¥à ¨§ è ¡«® ᮢ¯ «¨?
|
||
$JA G3 // <20>¥â - ᬮâਬ á«¥¤ãîéãî § ¯¨áì ¢ è ¡«®¥
|
||
EBX=0; // WBIT/RANDFLAG=0
|
||
DL=AL;
|
||
AL=OPERANDSIZE;
|
||
IF(DL==_B)&&(AL!=_B)BL++;
|
||
// $CMP DL,_B // ‚ è ¡«®¥ byte?
|
||
// $JNE G20
|
||
// $CMP AL,_B // Ž¯¥à ¤ byte?
|
||
// $JE G20
|
||
// BL++; // W-¡¨â=TRUE
|
||
//G20:
|
||
$CMP AL,_W // ‚ è ¡«®¥ word?
|
||
$JNE G30
|
||
$JA G30
|
||
BH++; // Ž¯¥à ¤ ®¡ï§ â¥«ì® ¤.¡. word - âॡã¥âáï ¯à¥ä¨ªá RAND
|
||
G30:
|
||
WBIT=BL;
|
||
RANDFLAG=BH; // ‡ ¯®¬¨¬ ¨ä®à¬ æ¨î ® ¯à¥ä¨ªá¥ ¨ W-¡¨â¥
|
||
G40:
|
||
AH&=NTRANSBITS; // Žáâ ¢¨¬ SOO ¡¨âë
|
||
}
|
||
}
|
||
}
|
||
AL=AH; // ‚®§¢à ⨬ SOO ¯®«¥
|
||
}
|
||
|
||
// ---- <20> §¡®àª è ¡«® ¤«ï ¤¢ã宯¥à ¤®© ¨áâàãªæ¨¨
|
||
GETOL2()
|
||
{
|
||
G7:
|
||
$LODSB // <20>®«ã稬 ¡ ©â ¨§ è ¡«®
|
||
AH=AL;
|
||
AL&=OLBITS; // ‚뤥«¨¬ ç¨á«® ®¯¥à ¤®¢
|
||
$CMP AL,OL2 // —¨á«® ®¯¥à ¤®¢ = 2?
|
||
$JE G8 // „ - 祬 ¯à®¢¥àªã
|
||
G9:
|
||
$LODSB // <20>®¨áª á«¥¤ãî饩 § ¯¨á¨ ¢ è ¡«®¥
|
||
$OR AL,AL // Š®¥æ § ¯¨á¨?
|
||
$JZ G7 // „ - ¯à®¢¥à¨¬ ®¢ãî § ¯¨áì
|
||
$CMP AL,_END // Š®¥æ è ¡«® ?
|
||
$JNE G9 // ‘¬®âਠ¤ «ìè¥ ¨ ç¥ - ®è¨¡ª
|
||
toomuchoperands();
|
||
$POP EAX;
|
||
$RET // ‚ë室 ¨§ MapOperands
|
||
G8:
|
||
AH&=NOLBITS; // ˆáª«î稬 ç¨á«® ®¯¥à ¤®¢
|
||
AL=AH;
|
||
AL&=TRANSBITS; // ‚뤥«¨¬ à §¬¥à ®¯¥à ¤
|
||
$CMP AL,_D
|
||
$JBE G100 // Ž¯¥à ¤ ¬.¡. à §¬¥à : byte, word, dword
|
||
G94:
|
||
$CMP AL,NB
|
||
$JB J0 //G95 // Ž¯¥à ¤ ¬.¡. à §¬¥à WB,DW OR BW.
|
||
AL-=NB; // <20>¥à¥áç¨â ¥¬ ¤«ï 䨪á¨à®¢ ëå à §¬¥à®¢: NB->B,OW->W, AF->D
|
||
G95:
|
||
$CMP AL,OPERANDSIZE // <20> §¬¥à ®¯¥à ¤ ¨ à §¬¥à ¨§ è ¡«® ᮢ¯ «¨?
|
||
$JNE G9 // <20> §¬¥àë ¥ ᮢ¯ «¨ - ¨é¥¬ á«¥¤ãîéãî § ¯¨áì
|
||
$JMP G11 // <20> §¬¥àë ᮢ¯ «¨ - ¯à®¤®«¦¨¬
|
||
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> §¬¥à ®¯¥à ¤ > dword - á«¥¤ãîéãî § ¯¨áì
|
||
$CMP OPERANDSIZE,AL
|
||
$JB NEAR G9 // <20> §¬¥àë ¥ ᮢ¯ «¨ - ¨é¥¬ á«¥¤ãîéãî § ¯¨áì
|
||
EBX=0;
|
||
DL=AL;
|
||
AL=OPERANDSIZE;
|
||
$CMP DL,_B // <20> §¬¥à ¢ è ¡«®¥ = byte?
|
||
$JNE G50
|
||
$CMP AL,_B // <20> §¬¥à ®¯¥à ¤ = byte?
|
||
$JE G50
|
||
BL++; // W-¡¨â=TRUE
|
||
G50:
|
||
$CMP AL,_W // ‚ è ¡«®¥ word?
|
||
$JNE G60
|
||
$JA G60
|
||
BH++; // Ž¯¥à ¤ ®¡ï§ â¥«ì® ¤.¡. word - âॡã¥âáï ¯à¥ä¨ªá RAND
|
||
G60:
|
||
WBIT=BL;
|
||
RANDFLAG=BH;
|
||
G11:
|
||
AH&=NTRANSBITS;
|
||
AL=AH; // ‚®§¢à ⨬ SOO ¯®«¥
|
||
}
|
||
|
||
// ---- <20> §¡®àª è ¡«® ¤«ï âà¥å®¯¥à ¤®© ¨áâàãªæ¨¨
|
||
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 // ‚ë室 ¨§ 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;
|
||
}
|
||
|
||
// ---- ƒ¥¥àà æ¨ï ModRM ¨ Sib
|
||
GETMODRMBYTE()
|
||
{
|
||
DL=EALENGTH; // Š®«¨ç¥á⢮ ॣ¨áâ஢ ¢ EA
|
||
$OR DL,DL // <20>¥â ॣ¨áâ஢ ¢ EA?
|
||
$JE NEAR C11 // „
|
||
$TEST EADESC,_W+_D*8
|
||
$JE NEAR E1 // 8-¡¨âë¥ à¥£¨áâàë ¥«ì§ï ¯à¨¬¥ âì ¢ ¤à¥á¥
|
||
$TEST EADESC,_W*8 // 16-¡¨âë© à¥£¨áâà?
|
||
$JNE NEAR E4 // 16-¡¨â ï ¤à¥á æ¨ï ¥ à §à¥è¥
|
||
GETEADISPX();
|
||
$CMP DH,2
|
||
$JNZ X00
|
||
EAX=opDescInd;
|
||
OPCONSTSIZE[EAX]=_D; // Ž¡ï§ â¥«ì® 32-¡¨âë© disp
|
||
X00:
|
||
DL--; // 1 ॣ¨áâà?
|
||
$JNE N1 // ¥â...
|
||
AL=EADESC&7;
|
||
$CMP EA_SIBFLAG,1 // ”« £ «¨ç¨ï Sib ¢ 32-¡¨â®¬ EA
|
||
$JNE L2 // <20>¥â Sib
|
||
EA_R2=5; // ”¨ªá¨à㥬 ¡ §®¢ë© ॣ¨áâà
|
||
EA_M=4;
|
||
EA_I=AL;
|
||
EDX=opDescInd;
|
||
$CMP OPCONSTFLAG[EDX],1 // ˆá¯®«ì§ã¥¬ disp?
|
||
$JE L1
|
||
EAX=0;
|
||
OPCONSTFLAG[EDX]=1;
|
||
EDX<<=2;
|
||
OPCONST[EDX]=EAX; // disp=0 ¢ 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
|
||
}
|
||
|
||
// ---- ˆ¨æ¨ «¨§ æ¨ï ¡ãä¥à áᥬ¡«¥à
|
||
INIT_LINE()
|
||
{
|
||
ECX=#opDescInd-#OPERANDSIZE;
|
||
AL=0;
|
||
EDI=#OPERANDSIZE;
|
||
$REP $STOSB;
|
||
AL=255;
|
||
OPERANDSIZE=AL;
|
||
SEGREGISTER=AL;
|
||
}
|
||
|
||
// ---- ‡ ¯¨áì ¯¥à¥®¯à¥¤¥«¥¨ï ᥣ¬¥â
|
||
WRITEOVERRIDE()
|
||
{
|
||
EBX=OVERRIDE;
|
||
IF(BL!=0){
|
||
AL=OVERRIDETAB[EBX]-rES;
|
||
OP();
|
||
}
|
||
}
|
||
|
||
// ---- ‡ ¯¨áì ¯à¥ä¨ªá à §¬¥à®á⨠®¯¥à ¤
|
||
WRITERAND()
|
||
{
|
||
$PUSH EAX
|
||
IF(RANDFLAG==1){
|
||
AL=0x66;
|
||
OP();
|
||
}
|
||
$POP EAX
|
||
}
|
||
|
||
// ---- ‡ ¯¨áì ª®áâ âë: CL=TYPE; EDI 㪠§ â¥«ì § 票¥
|
||
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();
|
||
}
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª Override
|
||
GETOVERRIDE()
|
||
{
|
||
IF(tok==tk_seg)&&(tok2==tk_colon){
|
||
IF(OVERRIDE==0){
|
||
OVERRIDE=number;
|
||
$STC // ù ᥣ¬¥â®£® ॣ¨áâà
|
||
}
|
||
ELSE preerror("ASM: Double segment override");
|
||
NextTok();
|
||
NextTok(); // <20>யã᪠¥¬ :
|
||
}
|
||
}
|
||
|
||
// ---- ‚ëç¨á«¥¨¥ à §¬¥à ®¯¥à ¤ : _B,_W,_D,WB,_DW & RAND-FLAG. AL=SIZE
|
||
DEF_OPSIZE()
|
||
{
|
||
AH=OPERANDSIZE;
|
||
IF(AH==255){
|
||
OPERANDSIZE=AL; // Ž¤¨ ®¯¥à ¤
|
||
return;
|
||
}
|
||
IF(AH==AL)return; // <20> §¬¥àë ᮢ¯ ¤ îâ
|
||
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;
|
||
}
|
||
}
|
||
|
||
// ---- ‡ ¯¨áì ¯à¥ä¨ªá ¤à¥á 樨
|
||
WRITEADDR()
|
||
{
|
||
$PUSH EAX
|
||
IF(ADDRFLAG==1){
|
||
AL=0x67;
|
||
OP();
|
||
}
|
||
$POP EAX
|
||
}
|
||
|
||
// ---- Ž¯à¥¤¥«¥¨¥ à §¬¥à®á⨠ª®áâ âë
|
||
DefConstSize()
|
||
{ // Ž¯à¥¤¥«¨¬ à §¬¥à®áâì ª®áâ âë
|
||
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;
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª ¬¥¬®¨ª¨ áᥬ¡«¥à
|
||
DoMnemonics()
|
||
{
|
||
opDescInd=0;
|
||
EADescInd=0;
|
||
INIT_LINE(); // Žç¨á⪠¡ãä¥à®¢
|
||
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>஢¥à¨¬ «¨ç¨¥ ¨áâàãªæ¨¨ ¡¥§ ®¯¥à ¤®¢
|
||
ACTUALMNEMDESC=EBX;
|
||
IF(tok2==tk_semicolon)NextTok();
|
||
ESI=ACTUALMNEMDESC;
|
||
$JMP CreateCode;// ƒ¥¥à æ¨ï ª®¤ ¤«ï ¨áâàãªæ¨¨ ¡¥§ ®¯¥à ¤®¢
|
||
}
|
||
}
|
||
ACTUALMNEMDESC=EBX; // ‡ ¯®¬¨¬ 㪠§ ⥫ì ⥪ã騩 è ¡«® ¬¥¬®¨ª¨
|
||
for(;;){ // –¨ª« «¨§ ®¯¥à ¤®¢
|
||
prevTok=tok;
|
||
NextTok(); // ‘«¥¤ãî騩 ®¯¥à ¤
|
||
FastSearch(#string,#St_Sizes);// <20>â® à §¬¥à ®¯¥à ¤ ?
|
||
IF(CARRYFLAG){ // „ : byte,word ¨«¨ dword
|
||
OPERANDSIZE=AL; // ‡ ¯®¬¨¬ _B,_W,_D
|
||
continue;
|
||
}
|
||
GETOVERRIDE(); // Ž¡à ¡®âª ª®áâàãªæ¨¨ SEG:
|
||
ContLine: // ’®çª ¤«ï ¯à®¤®«¦¥¨ï ®¡à ¡®âª¨ ⥪ã饣®
|
||
IF(tok==tk_eof)||(tok==tk_semicolon){
|
||
EBX=opDescInd;
|
||
IF(OPDESC[EBX]==E){ // Ž¡à ¡®âª ¢ EA?
|
||
DefConstSize();
|
||
GETMODRMBYTE(); // EOL - GENERATE MODRM OPCODE BYTE.
|
||
}
|
||
IF(prevTok!=tk_mnemonics){ // <20>뫨 ®¯¥à ¤ë
|
||
OPLENGTH++;
|
||
IF(OPERANDSIZE==255){
|
||
OPERANDSIZE=_D; // <20>à¨ã¤¨â¥«ì® ãáâ ®¢¨¬ dword
|
||
}
|
||
}
|
||
$JMP MapOperands
|
||
}
|
||
else IF(tok==tk_comma){
|
||
IF(opDescInd==3){
|
||
toomuchoperands();
|
||
break;
|
||
}
|
||
EBX=opDescInd;
|
||
IF(OPDESC[EBX]==E){ // Ž¡à ¡®âª ¢ EA?
|
||
DefConstSize();
|
||
GETMODRMBYTE(); // EOL - GENERATE MODRM OPCODE BYTE.
|
||
}
|
||
opDescInd++;
|
||
OPLENGTH++;
|
||
}
|
||
else IF(tok==tk_openblock){
|
||
EBX=opDescInd;
|
||
OPDESC[EBX]=E; // Žâ¬¥â¨¬, çâ® à ¡®â ¥¬ á EA ®¯¥à ¤®¬
|
||
}
|
||
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>த®«¦¨¬ docase ¡¥§ ¢ë¡®àª¨ á«¥¤.token
|
||
}
|
||
}
|
||
else IF(tok==tk_plus) continue;
|
||
else IF(tok==tk_mult){ // *
|
||
GETSCALING(); // “ª § ¬ áè ¡ ¢ Sib
|
||
}
|
||
else if(tok==tk_reg){ // Ž¡à ¡®âª ॣ¨áâà
|
||
G0:
|
||
EBX=opDescInd;
|
||
IF(OPDESC[EBX]==E){ // Ž¡à ¡®âª ¢ EA?
|
||
IF(type==tk_byte){
|
||
preerror("ASM: No byte register in address\n");
|
||
return;
|
||
}
|
||
IF(EALENGTH<2){ // Š®«¨ç¥á⢮ ॣ¨áâ஢ ¢ EA < 2 ?
|
||
EALENGTH++; // Žâ¬¥â¨¬, çâ® ¥áâì ¥é¥ ®¤¨ ॣ¨áâà ¢ EA
|
||
EBX=EADescInd;
|
||
EADESC[EBX]=number; // ‡ ¯®¬¨¬ ù ॣ¨áâà
|
||
EADescInd++;
|
||
}
|
||
ELSE{ // ‘«¨èª®¬ ¬®£® ॣ¨áâ஢ ¢ EA
|
||
preerror("ASM: too much registers in combination\n");
|
||
return;
|
||
}
|
||
}
|
||
ELSE{
|
||
OPDATA[EBX]=number; // ù ॣ¨áâà
|
||
OPDESC[EBX]=R;
|
||
AH=number&7;
|
||
EA_R=AH;
|
||
IF(opDescInd!=2){
|
||
AL>>=3;
|
||
DEF_OPSIZE();
|
||
}
|
||
}
|
||
}
|
||
else IF(tok==tk_number) { // Ž¡à ¡®âª ª®áâ âë
|
||
IF(tok2==tk_mult){
|
||
DoScale();
|
||
NextTok();
|
||
continue;
|
||
}
|
||
NUM:
|
||
EBX=opDescInd<<2;
|
||
OPCONST[EBX]+=number; // ‡ ¯®¬¨¬ ª®áâ âã
|
||
DefConstSize(); // Ž¯à¥¤¥«¨¬ à §¬¥à®áâì ª®áâ âë
|
||
IF(OPDESC[EBX]!=E) // Š®áâ â ¢ 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){ // ˆ¨æ¨ «¨§ æ¨ï EA á ª®áâ ⮩: EA+disp
|
||
AL=type-tk_byte>>1; // AL=à §¬¥à ¤à¥á㥬®£® ®¯¥à ¤ (_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; // Žâ¬¥â¨¬, çâ® à ¡®â ¥¬ á EA ®¯¥à ¤®¬
|
||
EBX<<=2;
|
||
OPCONST[EBX]+=number; // ‡ ¯®¬¨¬ ¤à¥á
|
||
}
|
||
else IF(tok==tk_seg){
|
||
EBX=opDescInd;
|
||
OPDATA[EBX]=number-rES; // ù ᥣ¬¥â®£® ॣ¨áâà
|
||
SEGREGISTER=AL;
|
||
AL<<=3; // ‘®§¤ âì ª®¤ ¤«ï XSM ¯®«ï
|
||
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; // Žâ¬¥â¨¬, çâ® à ¡®â ¥¬ á EA ®¯¥à ¤®¬
|
||
OPCONST[EBX]+=number; // ‡ ¯®¬¨¬ ¤à¥á
|
||
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){ // ”« £ «¨ç¨ï Sib ¢ 32-¡¨â®¬ EA
|
||
IF(EA_SCALE==0){ // Žâáãâáâ¢ã¥â
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
// ---- ƒ¥¥à æ¨ï ª®¤ . ESI=ptr § ¯¨áì ® ®¯¨á ¨¥ ¬¥¬®¨ª¨ (§ ¯¨áì ⨯ 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: // Ž¡à ¡®âª ¡ ©â ¨§ ¤¥áªà¨¯â®à ¬¥¬®¨ª¨
|
||
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 // Š®¥æ è ¡«® ¤«ï ¬¥¬®¨ª¨
|
||
E42:
|
||
preerror("Descriptor damaged\n");
|
||
return;
|
||
// OpCode - 1 ¡ ©â
|
||
Dsc_O:
|
||
AL=DSBYTE[EDI]+WBIT+DBIT;
|
||
EDI++;
|
||
OP();
|
||
GOTO NEXT_DESC_BYTE;
|
||
// OpCode - 1 á«®¢®
|
||
Dsc_OW:
|
||
AL=DSBYTE[EDI];
|
||
EDI++;
|
||
OP();
|
||
AL=DSBYTE[EDI]+WBIT+DBIT;
|
||
EDI++;
|
||
OP();
|
||
$JMP NEXT_DESC_BYTE
|
||
// OpCode - 1 ¡ ©â ¨ á«¥¤ãî騩 ¡ ©â, § ¤ ë© 8-à¨ç®© áâப®©
|
||
Dsc_OS:
|
||
AL=DSBYTE[EDI];
|
||
EDI++;
|
||
OP();
|
||
// OpCode - 8-à¨ç ï áâப á ª®¤®¬
|
||
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 ¡ ©â
|
||
Dsc_XRM:
|
||
AL=EA_X<<3|EA_R<<3|EA_M; // <20>®«ãç¨âì ॣ¨áâà ¨§ ®¯¨á ¨ï ¬¥¬®¨ª¨
|
||
GOTO N15;
|
||
// OpCode - ModRM á P-ä« £®¬ ( à¨ä¬¥â¨ç¥áª¨¥ ¨áâàãªæ¨¨)
|
||
Dsc_XPM:
|
||
AL=EA_X<<3|PFLAG<<3|EA_M;
|
||
GOTO N15;
|
||
// OpCode - ModRM á ᥣ¬¥âë¬ à¥£¨áâ஬
|
||
Dsc_XSM:
|
||
AL=EA_X<<3|SEGREGISTER<<3|EA_M;
|
||
GOTO N15;
|
||
// JMP NEXT_DESC_BYTE
|
||
}
|
||
|
||
// ---- <20> §¡®à § ª®ç¥ -> £¥¥à æ¨î ª®¤ ¯® è ¡«®ã
|
||
MapOperands()
|
||
{
|
||
// AL=0; WBIT=AL; DBIT=AL;
|
||
opDescInd=0;
|
||
ESI=ACTUALMNEMDESC; // “ª § â¥«ì ¨ä®à¬ æ¨î ¯® £¥¥à 樨
|
||
AL=OPLENGTH; // Š®«¨ç¥á⢮ ®¯¥à ¤®¢
|
||
ECX=#OPDESC; // “ª § â¥«ì ¨ä®à¬ æ¨î ®¡ ®¯¥à ¤ å
|
||
ECX=DSDWORD[ECX];
|
||
IF(ESI!=#T_MOV){ // ˆáâàãªæ¨ï MOV?
|
||
IF(AL!=0){
|
||
$CMP AL,1
|
||
$JE NEAR ONEOP // ˆáâàãªæ¨ï á ®¤¨¬ ®¯¥à ¤®¬
|
||
$CMP AL,2
|
||
$JE NEAR TWOOPS // ˆáâàãªæ¨ï á ¤¢ã¬ï ®¯¥à ¤ ¬¨
|
||
$CMP AL,3
|
||
$JE NEAR THREEOPS // ˆáâàãªæ¨ï á âà¥¬ï ®¯¥à ¤ ¬¨
|
||
toomuchoperands();
|
||
return;
|
||
}
|
||
// ---- ˆáâàãªæ¨ï ¡¥§ ®¯¥à ¤®¢
|
||
do{
|
||
$LODSB
|
||
IF(AL==0)goto CreateCode; // ƒ¥¥à æ¨ï ª®¤
|
||
}while(AL!=_END);
|
||
preerror("ASM: Operand required\n");
|
||
return;
|
||
// ---- ƒ¥¥à æ¨ï MOV ¨áâàãªæ¨¨
|
||
}
|
||
$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
|
||
// ---- ˆáâàãªæ¨ï á ®¤¨¬ ®¯¥à ¤®¬
|
||
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
|
||
// ‡¤¥áì ®¡à ¡®âª call&jmp
|
||
ECX=OPCONST[0]-OptImageBase-OptBaseOfCode-outptr+output; // <20> áç¥â ®â®á¨â¥«ì®£® ᬥ饨ï
|
||
$LODSB // <20>®«ã稬 short ¨«¨ 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>®¯à ¢ª à §¬¥à call ¨«¨ 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
|
||
// ---- ˆáâàãªæ¨ï á ¤¢ã¬ï ®¯¥à ¤ ¬¨
|
||
TWOOPS:
|
||
EBX=CL<<2+#Jmp_Op2;
|
||
$JMP NEAR DSDWORD[EBX] // <20>¥à¥å®¤ ¯® ⨯㠯¥à¢®£® ®¯¥à ¤
|
||
//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>¥à¢ë© ®¯¥à ¤ ¢ 2-®¯¥à ¤®© ¨áâàãªæ¨¨ - ॣ¨áâà
|
||
Op2R:
|
||
EBX=0;
|
||
BL=CH;
|
||
EBX=EBX<<2+#Jmp_Op2R;
|
||
$JMP NEAR DSDWORD[EBX] // <20>¥à¥å®¤ ¯® ⨯㠢â®à®£® ®¯¥à ¤
|
||
// <20>¥à¢ë© ®¯¥à ¤ ¢ 2-®¯¥à ¤®© ¨áâàãªæ¨¨ - EA
|
||
Op2E:
|
||
EBX=0;
|
||
BL=CH;
|
||
EBX=EBX<<2+#Jmp_Op2E;
|
||
$JMP NEAR DSDWORD[EBX] // <20>¥à¥å®¤ ¯® ⨯㠢â®à®£® ®¯¥à ¤
|
||
// mnem EA,RX
|
||
L81:
|
||
SCDEND();
|
||
OpE2R:
|
||
GETOL2(); // Ž¡à ¡®âª § ¯¨á¨ ¨§ è ¡«®
|
||
$CMP AL,DER //EA & R + D-BIT ?
|
||
$JE C21
|
||
X26:
|
||
$CMP AL,ERO //'ERO' ORDER ?
|
||
$JE C21
|
||
$CMP AL,EAO //EA, ?
|
||
$JNE L81 // <20> ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥
|
||
$CMP OPDATA[1],rCL //CL REGISTER USED??
|
||
$JNE L81 // <20> ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥
|
||
$CMP DSBYTE[ESI+1],rCL //CL IN GENERATION INFO?
|
||
$JNE L81 // <20> ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥
|
||
// CMP OPERANDSIZE,_B //YES, CHECK SIZE.
|
||
// JNE L81 // <20> ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥
|
||
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 // ¡ ©â+2®¯+EAold?
|
||
$JE W2 //EAO FOUND, R+R COMBINATION NOT PERMITTED.
|
||
GETOL2(); // Ž¡à ¡®âª § ¯¨á¨ è ¡«®
|
||
$CMP AL,DER // EA,reg ¨«¨ reg,EA á D/W-¡¨â®¬?
|
||
$JNE N53
|
||
LB2:
|
||
AL=OPDATA[0]; // <20>८¡à §ã¥¬ ॣ¨áâà ¢ EA
|
||
CREATE_EA();
|
||
AL=OPDATA[1]; // ‚â®à®© ®¯¥à ¤
|
||
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> ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥
|
||
W1:
|
||
ECX=2; //COMPARE 2 OPERANDS.
|
||
opDescInd=0;
|
||
LX2:
|
||
$LODSB // ¯®«¥ ¨§ § ¯¨á¨ è ¡«®
|
||
$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> ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥
|
||
OL2X_AR:
|
||
EBX=opDescInd;
|
||
AH=OPDATA[EBX]&7; // Ž¯¥à ¤ ¨§ ¬¥¬®¨ª¨
|
||
$JNZ NEAR LA1 // <20> ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥
|
||
L022:
|
||
opDescInd++;
|
||
$LOOP LX2
|
||
GOTO L23;
|
||
OL2X_DX:
|
||
EBX=opDescInd;
|
||
$CMP OPDATA[EBX],0o12
|
||
$JNE NEAR LA1 // <20> ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥
|
||
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>¥à¢ë© ®¯¥à ¤ ¢ 2-®¯¥à ¤®© ¨áâàãªæ¨¨ - ª®áâ â
|
||
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
|
||
// ’à¥å®¯¥à ¤ ï ¨áâàãªæ¨ï
|
||
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 // ”« £ «¨ç¨ï Sib ¢ 32-¡¨â®¬ EA
|
||
$JNE L3 // Sib ®âáãâáâ¢ã¥â
|
||
$CMP ADDRFLAG,1
|
||
$JE L3 //NO, NORMAL XRM
|
||
// ‡ ¯¨áì SIB - ¡ ©â
|
||
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; // ‡ 票¥ disp ¢ 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 ¨£¤¥ ¥ ®¯à¥¤¥«¥, ¤® ¡ã¤¥â à §¡¨à âìáï
|
||
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};
|