1
0
kolibrios/programs/develop/c--/trunk/generate.h--
Yogev Ezra 02b76505a6 Add sources of "C--"'like compiler written in C--.
git-svn-id: svn://kolibrios.org@1846 a494cfbc-eb01-0410-851d-a64ba20cac60
2011-02-05 16:39:49 +00:00

1719 lines
35 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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};