0,0 → 1,1718 |
dword ACTUALMNEMDESC; // ª § â¥«ì ®¯¨á ¨¥ ⥪ã饩 ¬¥¬®¨ª¨ |
byte ACTUALMNEMONIC; // ®¤ ⥪ã饩 ¬¥¬®¨ª¨ |
byte OPERANDSIZE; // §¬¥à ®¯¥à ¤ (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]; // «¨ç¨¥ ª®áâ âë ¢ ®¯¥à ¤¥ |
byte OPCONSTSIZE[3]; // §¬¥à®áâì ª®áâ âë ¢ ®¯¥à ¤¥ |
byte OPPOST[3]; |
dword OPPOSTREF[3]; |
byte PFLAG; // 票¥ P-ä« £ (®¬¥à ª« áá ). |
byte RANDFLAG; // TRUE: RAND: âॡã¥âáï ¯à¥ä¨ªá 0x66 |
byte ADDRFLAG; // TRUE: ADDR: âॡã¥âáï ¯à¥ä¨ªá 0x67 |
byte WBIT; // ¨â WORD ¢ OPCODE |
byte DBIT; // ¨â DIRECTION ¢ OPCODE |
byte OPLENGTH; // ®«¨ç¥á⢮ ®¯¥à ¤®¢ ¢ ⥪ã饩 ¨áâàãªæ¨¨ |
byte EA_M; // ©â 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; // ç «¥ ä ©« |
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++; |
} |
|
// ---- யã᪠¤® á«¥¤ãî饩 § ¯¨á¨ ¢ è ¡«®¥ ¨áâàãªæ¨¨ |
SCDEND() |
{ |
$LODSB |
IF(AL!=0){ |
$CMP AL,_END |
$JNE SCDEND |
illegaloperand(); |
$POP EAX; // ë室 ¨§ MapOperands |
} |
} |
|
GETSCALING() |
{ |
NextTok(); // ®«ã稬 § 票¥ ¬ áèâ ¡®£® ª®íää¨æ¨¥â |
IF(tok==tk_number){ |
DoScale: |
EA_SCALE=number; // Scale |
EA_SIBFLAG=1; // ⬥⨬ «¨ç¨¥ Sib ¢ 32-¡¨â®¬ EA |
} |
ELSE preerror("ASM: Illegal scaling value\n"); |
} |
|
// ---- ®¨áª ¢ è ¡«®¥ ¯®¤å®¤ï饩 ª ®¯¥à ¤ã § ¯¨á¨ (¤«ï ®¤®®¯¥à ¤®© ¨áâàãªæ¨¨) |
GETOL1() |
{ |
if(DSBYTE[ESI]!=0){ // áâàãªæ¨ï JMP - ¥ ¯à®¢¥à塞 ᮢ¯ ¤¥¨¥ à §¬¥à®¢ |
G4: |
$LODSB |
AH=AL&NOLBITS; // ᪫î稬 ç¨á«® ®¯¥à ¤®¢ |
if(NOTZEROFLAG){// â® ¢á¥-â ª¨ JMP... |
DL=AL&OPBITS; // ᪠¤«ï ⨯ ®¯¥à ¤ |
IF(DL!=SOO){ // ¯®«¥ à §¬¥à ®¯¥à ¤ ᮤ¥à¦¨âáï ¨ä®à¬ æ¨ï ® ⨯¥ ®¯¥à ¤ ? |
AL&=OLBITS; // 뤥«¨¬ ª®«¨ç¥á⢮ ®¯¥à ¤®¢ |
IF(AL!=OL1){ // ¡«® ¤«ï ¨áâàãªæ¨¨ á ®¤¨¬ ®¯¥à ¤®¬? |
G3: |
do{ |
$LODSB // à®á¬®âਬ á«¥¤ãîéãî § ¯¨áì è ¡«® |
IF(AL==0)GOTO G4; // ®¥æ § ¯¨á¨? |
}while(AL!=_END); // â® ª®¥æ è ¡«® ? |
illegaloperand(); // ¥â ¯®¤å®¤ï饩 § ¯¨á¨ ¤«ï â ª®© ¬¥¬®¨ª¨ |
$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; // ¥à¥áç¨â ¥¬ ¤«ï 䨪á¨à®¢ ëå à §¬¥à®¢: NB->B,OW->W, AF->D |
G90: |
$CMP AL,OPERANDSIZE // §¬¥à ®¯¥à ¤ ¨ à §¬¥à ¨§ è ¡«® ᮢ¯ «¨? |
$JNE G3 // ¥â - ᬮâਬ á«¥¤ãîéãî § ¯¨áì ¢ è ¡«®¥ |
GOTO G40; // §¬¥àë ᮢ¯ «¨ - ¯à®¤®«¦¨¬ |
G5: |
$CMP AL,OPERANDSIZE // §¬¥à ®¯¥à ¤ ¨ à §¬¥à ¨§ è ¡«® ᮢ¯ «¨? |
$JA G3 // ¥â - ᬮâਬ á«¥¤ãîéãî § ¯¨áì ¢ è ¡«®¥ |
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 ¯®«¥ |
} |
|
// ---- §¡®àª è ¡«® ¤«ï ¤¢ã宯¥à ¤®© ¨áâàãªæ¨¨ |
GETOL2() |
{ |
G7: |
$LODSB // ®«ã稬 ¡ ©â ¨§ è ¡«® |
AH=AL; |
AL&=OLBITS; // 뤥«¨¬ ç¨á«® ®¯¥à ¤®¢ |
$CMP AL,OL2 // ¨á«® ®¯¥à ¤®¢ = 2? |
$JE G8 // - 祬 ¯à®¢¥àªã |
G9: |
$LODSB // ®¨áª á«¥¤ãî饩 § ¯¨á¨ ¢ è ¡«®¥ |
$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; // ¥à¥áç¨â ¥¬ ¤«ï 䨪á¨à®¢ ëå à §¬¥à®¢: NB->B,OW->W, AF->D |
G95: |
$CMP AL,OPERANDSIZE // §¬¥à ®¯¥à ¤ ¨ à §¬¥à ¨§ è ¡«® ᮢ¯ «¨? |
$JNE G9 // §¬¥àë ¥ ᮢ¯ «¨ - ¨é¥¬ á«¥¤ãîéãî § ¯¨áì |
$JMP G11 // §¬¥àë ᮢ¯ «¨ - ¯à®¤®«¦¨¬ |
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 // §¬¥à ®¯¥à ¤ > dword - á«¥¤ãîéãî § ¯¨áì |
$CMP OPERANDSIZE,AL |
$JB NEAR G9 // §¬¥àë ¥ ᮢ¯ «¨ - ¨é¥¬ á«¥¤ãîéãî § ¯¨áì |
EBX=0; |
DL=AL; |
AL=OPERANDSIZE; |
$CMP DL,_B // §¬¥à ¢ è ¡«®¥ = byte? |
$JNE G50 |
$CMP AL,_B // §¬¥à ®¯¥à ¤ = 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 ¯®«¥ |
} |
|
// ---- §¡®àª è ¡«® ¤«ï âà¥å®¯¥à ¤®© ¨áâàãªæ¨¨ |
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 // ¥â ॣ¨áâ஢ ¢ 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 // ¥â 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(); // யã᪠¥¬ : |
} |
} |
|
// ---- ëç¨á«¥¨¥ à §¬¥à ®¯¥à ¤ : _B,_W,_D,WB,_DW & RAND-FLAG. AL=SIZE |
DEF_OPSIZE() |
{ |
AH=OPERANDSIZE; |
IF(AH==255){ |
OPERANDSIZE=AL; // ¤¨ ®¯¥à ¤ |
return; |
} |
IF(AH==AL)return; // §¬¥àë ᮢ¯ ¤ îâ |
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){ // ஢¥à¨¬ «¨ç¨¥ ¨áâàãªæ¨¨ ¡¥§ ®¯¥à ¤®¢ |
ACTUALMNEMDESC=EBX; |
IF(tok2==tk_semicolon)NextTok(); |
ESI=ACTUALMNEMDESC; |
$JMP CreateCode;// ¥¥à æ¨ï ª®¤ ¤«ï ¨áâàãªæ¨¨ ¡¥§ ®¯¥à ¤®¢ |
} |
} |
ACTUALMNEMDESC=EBX; // ¯®¬¨¬ 㪠§ ⥫ì ⥪ã騩 è ¡«® ¬¥¬®¨ª¨ |
for(;;){ // ¨ª« «¨§ ®¯¥à ¤®¢ |
prevTok=tok; |
NextTok(); // «¥¤ãî騩 ®¯¥à ¤ |
FastSearch(#string,#St_Sizes);// â® à §¬¥à ®¯¥à ¤ ? |
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){ // 뫨 ®¯¥à ¤ë |
OPLENGTH++; |
IF(OPERANDSIZE==255){ |
OPERANDSIZE=_D; // à¨ã¤¨â¥«ì® ãáâ ®¢¨¬ 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; // த®«¦¨¬ 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; // ®«ãç¨âì ॣ¨áâà ¨§ ®¯¨á ¨ï ¬¥¬®¨ª¨ |
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 |
} |
|
// ---- §¡®à § ª®ç¥ -> £¥¥à æ¨î ª®¤ ¯® è ¡«®ã |
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; // áç¥â ®â®á¨â¥«ì®£® ᬥ饨ï |
$LODSB // ®«ã稬 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 // ®¯à ¢ª à §¬¥à 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] // ¥à¥å®¤ ¯® ⨯㠯¥à¢®£® ®¯¥à ¤ |
//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; |
// ¥à¢ë© ®¯¥à ¤ ¢ 2-®¯¥à ¤®© ¨áâàãªæ¨¨ - ॣ¨áâà |
Op2R: |
EBX=0; |
BL=CH; |
EBX=EBX<<2+#Jmp_Op2R; |
$JMP NEAR DSDWORD[EBX] // ¥à¥å®¤ ¯® ⨯㠢â®à®£® ®¯¥à ¤ |
// ¥à¢ë© ®¯¥à ¤ ¢ 2-®¯¥à ¤®© ¨áâàãªæ¨¨ - EA |
Op2E: |
EBX=0; |
BL=CH; |
EBX=EBX<<2+#Jmp_Op2E; |
$JMP NEAR DSDWORD[EBX] // ¥à¥å®¤ ¯® ⨯㠢â®à®£® ®¯¥à ¤ |
// 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 // ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥ |
$CMP OPDATA[1],rCL //CL REGISTER USED?? |
$JNE L81 // ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥ |
$CMP DSBYTE[ESI+1],rCL //CL IN GENERATION INFO? |
$JNE L81 // ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥ |
// CMP OPERANDSIZE,_B //YES, CHECK SIZE. |
// JNE L81 // ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥ |
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]; // ८¡à §ã¥¬ ॣ¨áâà ¢ 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 // ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥ |
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; // ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥ |
OL2X_AR: |
EBX=opDescInd; |
AH=OPDATA[EBX]&7; // ¯¥à ¤ ¨§ ¬¥¬®¨ª¨ |
$JNZ NEAR LA1 // ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥ |
L022: |
opDescInd++; |
$LOOP LX2 |
GOTO L23; |
OL2X_DX: |
EBX=opDescInd; |
$CMP OPDATA[EBX],0o12 |
$JNE NEAR LA1 // ¯à®¯ã᪠§ ¯¨á¨ ¢ è ¡«®¥ |
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(); |
// ¥à¢ë© ®¯¥à ¤ ¢ 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}; |