byte Directives={ "IF","ELSE","ENDIF", // Условная компиляция "INCLUDE","DEFINE", // Включение файла/Определение константы "IMPORT", // Импорт из DLL по имени API "IMPORTN", // Импорт из DLL по номеру API "MAP", // Генерация MAP-файла "DEBUG", // Генерация отладочной информации "LIST", // Выдача ASM-листинга "DLL", // Генерация DLL-файла "DB","DW","DD", // Типы переменных "BYTE","CHAR","WORD","SHORT","DWORD","INT", "ENUM", // Нумерованные константы "STRUC", // Определение структуры "CYCLE","RETURN", "WHILE","DO","INLINE", "CONTINUE","BREAK", "DOCASE","CASE","DEFAULT", "CARRYFLAG","EXTRACT","FROM", "NOTCARRYFLAG","NOTOVERFLOW","OVERFLOW", "ZEROFLAG","NOTZEROFLAG",_END}; // ----- Для tokens, НЕ обрабатываемых через таблицу переключателей EMPTY() { WRITESTR(#string); WRITESTR("-ToDo\n"); NextTok(); } // ---- Возвращает адрес из Jmp_.... dword GetDirAddr(dword table,num) { EAX=num<<2+table; EAX=DSDWORD[EAX]; } // ----- Директива #define DirDefine() byte holdid[IDLENGTH]; dword next; { next=1; NextTok(); if(tok==tk_id){ lstrcpyA(#holdid,#string); // Имя константы NextTok(); IF(tok==tk_eof) unexpectedeof(); ELSE IF(tok==tk_number){ AddConstToTree(#holdid,DoConstLongMath()); next = 0; } ELSE IF(tok==tk_minus){ IF(tok2==tk_number) { AddConstToTree(#holdid,DoConstLongMath()); next = 0; } } ELSE IF(tok==tk_undefproc){ tok = tk_id; AddToTree(#holdid); } ELSE AddToTree(#holdid); } ELSE idexpected(); IF(next)NextTok(); } // -- #enum DirEnum() dword counter; byte holdid[IDLENGTH]; { counter=0; NextTok(); IF(tok!=tk_openbrace)expected('{'); for(;;){ NextTok(); IF(tok==tk_id){ lstrcpyA(#holdid,#string); IF( tok2 == tk_assign ){ NextTok(); NextTok(); IF(tok==tk_number)counter=DoConstLongMath(); ELSE numexpected(); } AddConstToTree(#holdid,counter); counter++; CONTINUE; } IF(tok==tk_comma)CONTINUE; IF(tok==tk_semicolon)BREAK; } NextTok(); } // Директива #import DirImport() { NextTok(); IF(tok==tk_string)GetImport(1); // import по имени API-функций ELSE stringexpected(); NextTok(); } // Директива #importN DirImportN() { NextTok(); IF(tok==tk_string)GetImport(0); // import по имени API-функций ELSE stringexpected(); NextTok(); } // ---- Импорт из DLL GetImport(dword byName) dword dll; dword dllpos,base,export,fptr,i,nexports,nsect,delta; byte path[80],name[120]; dword tok0,type0,src0,post0; dword number0; dword ord; dword pname1,pname2,j; { pname1 = 0; ord=0; importFlag=1; IF(DLLcount>=MAXDLLS)outofmemory2(); IF(SearchTree(#tok0,#type0,#src0,#post0,#string,#number0))return; // DLL уже импортирован wsprintfA(#name,"%s",#string); dll=_lopen(#name,0); IF(dll== -1){ GetSystemDirectoryA(#path,80); wsprintfA(#name,"%s\\%s",#path,#string); dll=_lopen(#name,0); IF(dll==-1) { unabletoopen(#string); return; } } nsect=0; _llseek(dll,0x3c,0); _lread(dll,#fptr,4); _llseek(dll,fptr+120,0); _lread(dll,#export,4); // Get export address IF(export==0) { wsprintfA(#mapstr,"ERROR: No export directory in file %s.\n",#string); preerror(#mapstr); return; } _llseek(dll,fptr+6,0); _lread(dll,#nsect,2); // Number of sections delta=export; i=1; while(i<=nsect){ EAX=i; EAX--; EAX=EAX*40; EAX+=260; EAX+=fptr; // fptr+260+40*(i-1) _llseek(dll,EAX,0); _lread(dll,#base,4); // RVA of section IF(base<=export){ EAX=export-base; IF(EAXi){ EAX=i; EAX<<=1; EAX+=fptr; // fptr+2*i _llseek(dll,EAX,0); _lread(dll,#ord,2);// Ordinal number EAX=i; EAX<<=2; EAX+=base; // base+4*i _llseek(dll,EAX,0); _lread(dll,#pname1,8); // address of name _llseek(dll,pname1+delta,0); _lread(dll,#string,pname2-pname1);// address of Ordinal Table number=ord+1; // при загрузке используется номер на 1 больше экспортируемого из DLL AddToTree(#string); // SHOW(#string);SHOW("\n"); i++; } EAX=i; EAX<<=1; EAX+=fptr; // fptr+2*i _llseek(dll,EAX,0); _lread(dll,#ord,2); // Ordinal number j=0; for(;;){ _llseek(dll,pname2+delta+j,0); EAX=j; _lread(dll,#string[EAX],1); EAX=j; IF(string[EAX]==0)BREAK; j++; } number=ord+1; AddToTree(#string); tok=tok0; number=number0;src=src0;type=type0;post=post0; _lclose(dll); DLLcount++; importFlag=0; } // ----- Директива #include DirInclude() byte s[STRLEN],s2[STRLEN]; { NextTok(); if(tok==tk_string) { AL=cha2; $PUSH EAX,linenum2,inptr2,number,tok2,tok,input,inptr,endoffile, displaytokerrors,currmod; lstrcpyA(#s,#string); lstrcpyA(#s2,#string2); Preview(#s); lstrcpyA(#string,#s); lstrcpyA(#string2,#s2); $POP currmod,displaytokerrors,endoffile,inptr,input,tok,tok2,number,inptr2, linenum2,EAX; cha2=AL; NextTok(); } ELSE stringexpected(); } // ----- Директива list DirList() { IF(mapfile==0){ makemapfile=1; StartMapfile(); } list^=1; // Переключение вывода листинга NextTok(); } // ----- Директива map DirMap() { makemapfile = 1; StartMapfile(); NextTok(); } // ---- Обработка глобальной переменной или процедуры с типом GetProc(dword vartype) dword src0,beg,count; byte var_name[IDLENGTH]; { lstrcpyA(#var_name,#string); // Имя процедуры beg=inptr2; // отметим начало описания count=0; EAX=0; // ищем начало блока процедуры modline=currmod<<16+linenum2; for(;;){ ESI>0)loop(i)OP(byte 0); } else IF(tok==tk_from){ NextTok(); WRITESTR("count = DoFrom(1);\n"); i=size*elements; i-=count; loop(i)OP(byte 0); NextTok(); } else IF(tok==tk_extract){ NextTok(); WRITESTR("count = DoExtract(1);\n"); i=size*elements; i-=count; loop(i)OP(byte 0); } else if(tok==tk_openbrace){ // varname={...}; ESI=ptr; // Откорректируем ранее сделанную запись DSDWORD[ESI+recnumber] = outptr-output+OptImageBase+OptBaseOfCode; DSDWORD[ESI+recpost] = 0; count = 0; NextTok(); for(;;){ IF(tok==tk_closebrace)break; ELSE IF(tok==tk_comma)NextTok(); else IF(tok==tk_plus)NextTok(); else IF(tok==tk_string){ i=number; EDX=#string; loop(i){ OP(DSBYTE[EDX]); EDX++; count++; } IF(tok2!=tk_plus){ OP(byte 0); count++; } NextTok(); } else IF(tok==tk_postnumber){ SetPost(treeptr,POST_DATA); OUTDWORD(number); NextTok(); } else IF(tok==tk_number){ G02: IF(vartype==tk_byte)OP(byte DoConstDwordMath()); ELSE IF(vartype==tk_word)OUTWORD(DoConstDwordMath()); ELSE IF(vartype==tk_char)OP(byte DoConstLongMath()); ELSE IF(vartype==tk_short) OUTWORD(DoConstLongMath()); ELSE IF(vartype==tk_dword) OUTDWORD(DoConstDwordMath()); ELSE IF(vartype==tk_int) OUTDWORD(DoConstLongMath()); count++; } ELSE IF(tok==tk_minus){ NextTok(); number=-number; goto G02; } ELSE{ numexpected(); NextTok(); } } count=elements-count; IF(count>0){ loop(count){ IF(size==1)OP(byte 0); ELSE IF(size==2)OUTWORD(0); ELSE IF(size==4)OUTDWORD(0); } } } ELSE{ G04: ESI=ptr; DSDWORD[ESI+recnumber] = postsize; DSDWORD[ESI+recpost] = 1; postsize = elements * size + postsize; BREAK; } } } //===== Таблица переключателей директив dword Jmp_Directives={ // "if","else","endif", // Условная компиляция #EMPTY,#EMPTY,#EMPTY, // "include","define", // Включение фа ла #DirInclude,#DirDefine, // "import", // Импорт из DLL #DirImport, // "importN", // Импорт из DLL #DirImportN, // "map", // Генерация MAP-файла #DirMap, // "debug", // Генерация отладочной информации #EMPTY, // "list", // Выдача ASM-листинга #DirList, // "dll", // Генерация DLL-файла #EMPTY, // "db","dw","dd", // Типы переменных #EMPTY,#EMPTY,#EMPTY, // "byte","char","word","short","dword","int", #EMPTY,#EMPTY,#EMPTY,#EMPTY,#EMPTY,#EMPTY, // "enum", // Нумерованные константы #DirEnum, // "struc", // Определение структуры #EMPTY, // "cycle","return", #EMPTY,#EMPTY, // "while","do","inline", #EMPTY,#EMPTY,#EMPTY, // "continue","break", #EMPTY,#EMPTY, // "docase","case","default", #EMPTY,#EMPTY,#EMPTY, // "CARRYFLAG","extract","from", #EMPTY,#EMPTY,#EMPTY, // "NOTCARRYFLAG","NOTOVERFLOW","OVERFLOW", #EMPTY,#EMPTY,#EMPTY, // "ZEROFLAG","NOTZEROFLAG" #EMPTY,#EMPTY }; //===== Таблица переключателей команд dword Jmp_Commands={ // "if","else","endif", // Условная компиляция #CmdIf,#CmdElse,#EMPTY, // "include","define", // Включение фа ла #EMPTY,#EMPTY, // "import","importN", // Импорт из DLL #EMPTY,#EMPTY, // "map", // Генерация MAP-файла #EMPTY, // "debug", // Генерация отладочно информации #EMPTY, // "list", // Выдача ASM-л стинга #EMPTY, // "dll", // Генерация DLL-файла #EMPTY, // "db","dw","dd", // Типы переменных #CmdDb,#CmdDw,#CmdDd, // "byte","char","word","short","dword","int", #CmdByte,#CmdChar,#CmdWord,#CmdShort,#CmdDword,#CmdInt, // "enum", // Нумерованные константы #CmdEnum, // "struc", // Определение структуры #EMPTY, // "cycle","return", #CmdCycle,#CmdReturn, // "while","do","inline", #CmdWhile,#CmdDo,#EMPTY, // "continue","break", #CmdContinue,#CmdBreak, // "docase","case","default", #CmdDoCase,#CmdCase,#CmdDefault, // "CARRYFLAG","extract","from", #CmdCarryFlag,#EMPTY,#EMPTY, // "NOTCARRYFLAG","NOTOVERFLOW","OVERFLOW", #CmdNotCarryFlag,#CmdNotOverflow,#CmdOverflow, // "ZEROFLAG","NOTZEROFLAG" #CmdZeroFlag,#CmdNotZeroFlag };