From 1db3b2cf18474b6305d664a45f641ead2690ec4d Mon Sep 17 00:00:00 2001 From: "Kirill Lipatov (Leency)" Date: Sun, 16 Dec 2012 16:59:21 +0000 Subject: [PATCH] /develop/c-- deleted as too old version of C--, not needed git-svn-id: svn://kolibrios.org@3119 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/develop/c--/trunk/32.c-- | 1441 -------------- .../develop/c--/trunk/ORIGINAL_LICENSE.txt | 152 -- programs/develop/c--/trunk/data.h-- | 157 -- programs/develop/c--/trunk/directiv.h-- | 986 ---------- programs/develop/c--/trunk/enums.h-- | 109 -- programs/develop/c--/trunk/examples/docase.c- | 17 - .../develop/c--/trunk/examples/docase.map | 71 - programs/develop/c--/trunk/exe.h-- | 145 -- programs/develop/c--/trunk/generate.h-- | 1718 ----------------- programs/develop/c--/trunk/opcodesc.h-- | 591 ------ programs/develop/c--/trunk/parser.h-- | 630 ------ programs/develop/c--/trunk/readme_ru.txt | 529 ----- programs/develop/c--/trunk/tokscan.h-- | 666 ------- programs/develop/c--/trunk/tree.h-- | 461 ----- programs/develop/c--/trunk/wapi.h-- | 36 - 15 files changed, 7709 deletions(-) delete mode 100644 programs/develop/c--/trunk/32.c-- delete mode 100644 programs/develop/c--/trunk/ORIGINAL_LICENSE.txt delete mode 100644 programs/develop/c--/trunk/data.h-- delete mode 100644 programs/develop/c--/trunk/directiv.h-- delete mode 100644 programs/develop/c--/trunk/enums.h-- delete mode 100644 programs/develop/c--/trunk/examples/docase.c- delete mode 100644 programs/develop/c--/trunk/examples/docase.map delete mode 100644 programs/develop/c--/trunk/exe.h-- delete mode 100644 programs/develop/c--/trunk/generate.h-- delete mode 100644 programs/develop/c--/trunk/opcodesc.h-- delete mode 100644 programs/develop/c--/trunk/parser.h-- delete mode 100644 programs/develop/c--/trunk/readme_ru.txt delete mode 100644 programs/develop/c--/trunk/tokscan.h-- delete mode 100644 programs/develop/c--/trunk/tree.h-- delete mode 100644 programs/develop/c--/trunk/wapi.h-- diff --git a/programs/develop/c--/trunk/32.c-- b/programs/develop/c--/trunk/32.c-- deleted file mode 100644 index 9250ebfc38..0000000000 --- a/programs/develop/c--/trunk/32.c-- +++ /dev/null @@ -1,1441 +0,0 @@ -//===== Флаги компиляции -#pragma option w32c -#stack 0x8000 -#argc TRUE - -//===== Подключаемые модули -#include "wapi.h--" -#include "enums.h--" -#include "data.h--" -#include "opcodesc.h--" -#include "tree.h--" -#include "directiv.h--" -#include "tokscan.h--" -#include "exe.h--" -#include "generate.h--" -#include "parser.h--" - -//===== Главная функция программы -main() -dword count,pari,cmdline; -{ - stdout=GetStdHandle(STD_OUTPUT_HANDLE); - WRITESTR("\n32-Compiler Version 0.01\tXAC (C) 1999."); - WRITESTR("\nBased on SPHINX C-- Compiler Peter Cellik (C) 1995.\n"); -// Разбор коммандной строки: 32.exe [/map] [/debug] - pari=@PARAMCOUNT(); - for(count=1;count Unknown command line option: '"); - WRITESTR(cmdline); - WRITESTR("'\n"); - ExitProcess(e_unknowncommandline); - } - } - ELSE{ // Копируем имя исходного файла без расширения - EDI=#rawfilename; - for(;;){ - $LODSB - IF(AL=='.')||(AL==0)BREAK; // Есть расширение? - $STOSB; - } - AL=0; - $STOSB; - lstrcpyA(#inputfile,cmdline); // Копируем имя входного файла с расширением - } - } - IF(rawfilename[0]==0){ - errmsg(); - WRITESTR("No input file specified"); - pari=1; - } - IF(pari < 2){ - WRITESTR("\nUsage: 32.exe [/MAP] [/DEBUG] "); - WRITESTR("\n\t/MAP\t<< generate map file"); - WRITESTR("\n\t/DEBUG\t<< generate .TDS - debug info file\n"); - ExitProcess(e_noinputspecified); - } - GetMem(); // выделение памяти для компиляции - TokInit(); // инициализация списков - Compile(); - IF( error == 0 )EAX=e_ok; - ELSE EAX=e_someerrors; - ExitProcess(EAX); -} - -//===== Компилятор -Compile() -{ - IF(makemapfile)StartMapfile(); - WRITESTR("Compiling ...\n"); - Preview(#inputfile); - CompileAll(); -/*if( endifcount > 0 ) - preerror("#endif expected before end of file"); -if( outptr%16 != 0 ) // paragraph align the end of the code seg - outptr += 16 - outptr%16;*/ - DoLink(); // Формирование link - IF(posts > 0)DoPosts(); // Обновление всех post адресов - SeekUndefined(treestart); - if(error==0){ - wsprintfA(#mapstr,"\nCOMPILING FINISHED.\tErrors: %d\tLines: %u\n",error,totallines); - WRITESTR(#mapstr); - runfilesize = outptr-output; - postsize += postsize%2; - PrintMemsizes(GetStdHandle(STD_OUTPUT_HANDLE)); - IF(WriteEXE()==0) { - wsprintfA(#mapstr,"\nRun File Saved (%ld bytes).\n",runfilesize); - WRITESTR(#mapstr); - wsprintfA(#mapstr,"DLL: %d\tAPI: %d \n",DLLcount,APIcount); - WRITESTR(#mapstr); - } -// if(dbg) -// dotds(); // do turbo debugger line info - } - IF(makemapfile)FinishMapfile(); -} - -// ---- Предварительная обработка файла -Preview(dword filename) -long hold; -char trialfilename[FILENAMESIZE]; -{ - lstrcpyA(#trialfilename,filename); - hold = LoadInputfile(#trialfilename); - IF(EAX==-2)unabletoopen(#trialfilename); - IF(hold!=0)ExitProcess(e_cannotopeninput); - lstrcpyA(#currentfilename,#trialfilename); - module++; - IF(module>16; - lstrcpyA(#currentfilename,FILENAMESIZE*currmod+#modules); - NextChar(); - cha2 = cha; - inptr2=inptr; - IF(tok==tk_proc){ - Proc(cpt_near); - DoPoststrings(); - } - ELSE IF(tok==tk_var)GlobalVar(type); - ELSE preerror("Bad input format\n"); - } - ELSE{ // post-переменная без размерности - ESI=ptr; - DSDWORD[ESI+recnumber] = postsize; - DSDWORD[ESI+recpost] = 1; - postsize+=TypeSize(type); - } -} - -// ---- Компиляция всех процедур и объявлений данных -CompileAll() -{ - IF(SearchTree(#tok,#type,#src,#post,"main",#number))AX=3; // Console - ELSE IF(SearchTree(#tok,#type,#src,#post,"WinMain",#number))AX=2; // GUI - ELSE{ - preerror("Main not found"); - return; - } - OptSubSystem=AX; - OptEntryPointRVA=OptBaseOfCode+outptr-output; - CompileSrc(treeptr); // Компиляция main - WHILE(SeekToDo(treestart)){ - ESI=treeptr; - wsprintfA(#mapstr,"==>%3d %8lXh %8lXh %6Xh\t%s\n",DSDWORD[ESI+rectok], - DSDWORD[ESI+rectype],DSDWORD[ESI+recnumber],DSDWORD[ESI+recpost], - DSDWORD[ESI+recid]); - fprint(mapfile,#mapstr); - CompileSrc(treeptr); // Компиляция исходников - } - IF(makemapfile) - fprint(mapfile,"Compile all sources\n"); -} - -// ---- Обработка параметров при объявлении процедуры -DeclareParams() -dword paramtok,paramtype; -{ -LL: - IF(tok==tk_command)GetDirAddr(#Jmp_Commands,number); - ELSE EAX=-1; - IF(EAX==#CmdShort){ - paramtok = tk_param; - paramtype=tk_short; - } - ELSE IF(EAX==#CmdWord){ - paramtok = tk_param; - paramtype=tk_word; - } - ELSE IF(EAX==#CmdChar){ - paramtok = tk_param; - paramtype=tk_char; - } - ELSE IF(EAX==#CmdByte){ - paramtok = tk_param; - paramtype=tk_byte; - } - ELSE IF(EAX==#CmdInt){ - paramtok = tk_param; - paramtype=tk_int; - } - ELSE IF(EAX==#CmdDword){ - paramtok = tk_param; - paramtype=tk_dword; - } - ELSE{ - datatype_expected(); - NextTok(); - } - for(;;){ - NextTok(); - IF(tok==tk_id ){ - paramsize += 4; - AddLocalvar(#string,paramtok,paramtype,paramsize); - } - ELSE IF(tok==tk_semicolon){ - NextTok(); - $JMP LL - } - ELSE IF(tok==tk_closebracket)BREAK; - ELSE IF(tok!=tk_comma)idexpected(); - } -} - -// ---- Обработка локальных переменных при объявлении процедуры -DeclareLocals() -dword size; -dword loctok,loctype; -{ -LL: - IF(tok==tk_command)GetDirAddr(#Jmp_Commands,number); - IF(EAX==#CmdShort){ - loctok = tk_local; - loctype=tk_short; - size = 2; - } - else IF(EAX==#CmdWord){ - loctok = tk_local; - loctype=tk_word; - size = 2; - } - else IF(EAX==#CmdChar){ - loctok = tk_local; - loctype=tk_char; - size = 1; - } - ELSE IF(EAX==#CmdByte){ - loctok = tk_local; - loctype=tk_byte; - size = 1; - } - ELSE IF(EAX==#CmdInt){ - loctok = tk_local; - loctype=tk_int; - size = 4; - } - ELSE IF(EAX==#CmdDword){ - loctok = tk_local; - loctype=tk_dword; - size = 4; - } - ELSE IF(tok==tk_eof)||(tok==tk_openbrace)$JMP L1 - ELSE{ - datatype_expected(); - NextTok(); - goto LL; - } - for(;;){ - NextTok(); - IF(tok==tk_id){ - AddLocalvar(#string,loctok,loctype,localsize); - IF(tok2==tk_openblock){ - NextTok(); - NextTok(); - localsize += DoConstLongMath()*size; - EAX=localsize; - $TEST EAX,3; - IF(NOTZEROFLAG){ - EAX=EAX>>2+1<<2; - localsize=EAX; // Выравнивание на dword - } - expecting(tk_closeblock); - } - ELSE localsize+=4; - } - ELSE IF(tok==tk_semicolon){ - NextTok(); - $JMP LL - } - ELSE IF(tok==tk_openbrace)||(tok==tk_eof)BREAK; - ELSE IF(tok!=tk_comma)idexpected(); - } -L1: - IF(paramsize==0)Asm("push ebp; mov ebp,esp;"); - wsprintfA(#mapstr,"sub esp,%d;",localsize); - Asm(#mapstr); -} - -// ---- Обработка обращения к уже описанной процедуре -DoAnyProc() -byte s[80]; -{ - wsprintfA(#s,"call %s;",#string); - NextTok(); - DoParams(); - Asm(#s); -} - -// ---- Обработка ранее объвленной, но пока не известной метки -dword DoAnyUndefproc(dword expectedreturn) -byte s[80]; -{ - IF( tok2 == tk_colon ){ // метка - number = outptr-output+OptImageBase+OptBaseOfCode; - tok = tk_proc; - ESI=treeptr; - DSDWORD[ESI+rectok] = tok; - DSDWORD[ESI+recnumber] = number; - DSDWORD[ESI+recpost] = 0; - NextTok(); // move past id - NextTok(); // move past : - RETURN(tokens); - } - IF( tok2 == tk_openbracket ){ - wsprintfA(#s,"call %s;",#string); - NextTok(); - DoParams(); - Asm(#s); - RETURN(tk_dword); - } - undefinederror(); - NextTok(); - return(tk_int); -} - -// ---- Обработка обращения к API функции -dword doAPI() -dword hold; -byte s[IDLENGTH]; -{ - if( tok2 == tk_openbracket ){ - hold = treeptr; - GetVarname(#s); - NextTok(); - DoParams(); - IF(posts>=MAXPOSTS){ - preerror("maximum number of API procedure calls exceeded"); - return(tokens); - } - EBX=hold; - IF(DSDWORD[EBX+recpost]==0) { // Первый вызов API? - DSDWORD[EBX+recpost]=1; // отметим вызов данной API - APIcount++; - EAX=DSDWORD[EBX+rectype]; // Указатель на DLL, в котором находится API - DSDWORD[EAX+recmodline]++; // Увеличим счетчик API, вызванных из DLL - } - OUTWORD(0x15FF); // call [dword] - SetPost(hold,POST_API); - OUTDWORD(0); - IF(list){ - fprint(mapfile,"\t//\tcall "); - fprint(mapfile,#s); - fprint(mapfile,"\n"); - } - return(tk_int); - } - undefinederror(); - NextTok(); - return(tokens); -} - -// ---- Обработка программного блока {...} -void DoBlock() -{ - expecting(tk_openbrace); - for(;;){ - IF(tok==tk_eof){ - unexpectedeof(); - BREAK; - } - IF(tok == tk_closebrace){ - NextTok(); - BREAK; - } - DoCommand(); - } -} - -// ---- Обработка одной команды внутри блока -DoCommand() -{ -LL: - FastSearch(#string,#St_Sizes);// Это размер операнда? - IF(CARRYFLAG){ // Да: byte,word или dword - type=EAX<<1+tk_byte; - string[0]=0; - tok=tk_var; - GOTO LL; - } - IF(tok==tk_mnemonics){ - DoMnemonics(); - NextTok(); - } - else IF(tok==tk_directive){ - GetDirAddr(#Jmp_Directives,number); - EAX(); - } - else IF(tok==tk_command){ - GetDirAddr(#Jmp_Commands,number); - EAX(); - } - else IF(tok==tk_id){ - DoId(tk_void); - IF(EAX!=tokens)NextSemiNext(); - } - else IF(tok==tk_undefproc){ - DoAnyUndefproc(tk_void); - IF(EAX!=tokens)NextSemiNext(); - } - else IF(tok==tk_proc){ - DoAnyProc(); - NextSemiNext(); - } - else IF(tok==tk_API){ - IF(doAPI()!=tokens)NextSemiNext(); - } - else IF(tok==tk_var)||(tok==tk_local)||(tok==tk_param)||(tok==tk_reg)DoVar(type); - ELSE IF(tok==tk_openblock)DoVar(tk_dword); - ELSE IF(tok==tk_string){ - Macros(); - NextSemiNext(); - } - ELSE IF(tok==tk_locallabel)DoLocalPost(); - ELSE IF(tok==tk_openbrace)DoBlock(); - ELSE IF(tok==tk_comma)||(tok==tk_semicolon)NextTok(); - ELSE IF(tok==tk_eof)unexpectedeof(); - /* case tk_from: - NextTok(); DoFrom(0); NextSemiNext(); break; - case tk_extract: - NextTok(); DoExtract(0); SemiNext(); break; - */ -} - -// ---- Обработка новых идентификаторов -dword DoId(dword expectedreturn) -byte s[80]; -{ - IF(tok2 == tk_colon){ // метка? - number = outptr-output+OptImageBase+OptBaseOfCode; - tok = tk_proc; - post = 0; - AddToTree(#string); - NextTok(); NextTok(); // пропустим идентификатор и : - EAX=tokens; - } - ELSE IF(tok2 == tk_openbracket){ // вызов процедуры - wsprintfA(#s,"call %s;",#string); - tok = tk_undefproc; - number=0; - post=1; - AddToTree(#string); - NextTok(); - DoParams(); - Asm(#s); - EAX=expectedreturn; - } - ELSE{ - undefinederror(); - NextTok(); - EAX=tk_int; - } -} - -// ---- Обработка параметров при вызове процедуры -DoParams() -{ - IF(tok==tk_openbracket){ - inptr2--; - DoParam(); - NextTok(); - } - ELSE expecting(tk_openbracket); -} - -// ---- Обработка ... -DoVar(dword vartype) -dword next,vtok; -byte varName[2*IDLENGTH]; -byte varName2[2*IDLENGTH]; -{ - next=1; - vtok=GetVarname(#varName); - NextTok(); - IF(tok==tk_assign){ - NextTok(); - IF(tok2notstopper()){ - DoExpr(#varName,vtok,vartype,"mov"); - next=0; - } - ELSE GetIntoVar(#varName,vtok,vartype); - } - else IF(tok==tk_minusminus){ // Var--; - wsprintfA(#mapstr,"dec %s",#varName); - Asm(#mapstr); - } - else IF(tok==tk_plusplus){ // Var++; - wsprintfA(#mapstr,"inc %s",#varName); - Asm(#mapstr); - } - else IF(tok==tk_plusequals){ // Var+=Expr; - NextTok(); - DoExpr(#varName,tk_var,vartype,"add"); - next=1; - } - else IF(tok==tk_minusequals){ // Var-=Expr; - NextTok(); - DoExpr(#varName,tk_var,vartype,"sub"); - next=1; - } - else IF(tok==tk_andequals){ // Var&=Expr; - NextTok(); - DoExpr(#varName,tk_var,vartype,"and"); - next=1; - } - else IF(tok==tk_xorequals){ // Var^=Expr; - NextTok(); - DoExpr(#varName,tk_var,vartype,"xor"); - next=1; - } - else IF(tok==tk_orequals){ // Var|=Expr; - NextTok(); - DoExpr(#varName,tk_var,vartype,"or"); - next=1; - } - else if(tok==tk_swap){ // Var>>=Expr; - NextTok(); - IF(tok == tk_number)wsprintfA(#mapstr,"shr %s,%d",#varName,DoConstMath()); - ELSE{ - Expression("cl",tk_reg,tk_byte); - wsprintfA(#mapstr,"shr %s,cl",#varName); - next=0; - } - Asm(#mapstr); - } - ELSE operatorexpected(); - IF(next)NextSemiNext(); - ELSE SemiNext(); -} - -// ---- Обработка ссылок вперед -DoPosts() -dword addhold,i; -{ - i=0; - while(i db 4,'AA',1,'AD',2,'BC',_END -// +-----+ -// | 'B' | ---> db 6,'AC',3,'AR",_END -// +-----+ -// | ... | -// +-----+ -// | 'Z' | ---> db 0,'AK',5,'Z',_END -// +-----+ -InitList(dword keylist,table) -dword ptr; -{ - ptr=LocalAlloc(0x40,SORTSIZE*256); - IF(EAX==NULL)outofmemory2(); - EDI>'9')EAX=0; - ELSE EAX=1; -} - -// ---- Чтение входного файла в буфер -long LoadInputfile(dword infile) -dword fhandle, size; -{ - fhandle=_lopen(infile,0); - IF(EAX==-1){ - GetLastError(); - return(-2); - } - EAX=GetFileSize(EAX,0); - IF(EAX==-1){ - unabletoopen(infile); - _lclose(fhandle); - return(-1); - } - size=EAX; - input=LocalAlloc(0x40,EAX+2); // Заполненная нулями - IF(EAX==NULL){ - preerror("Not enough memory for input buffer"); - _lclose(fhandle); - RETURN(-1); - } - EAX=_lread(fhandle,input,size); - IF(EAX!=size){ - preerror("File Read error"); - _lclose(fhandle); - RETURN(-1); - } - _lclose(fhandle); - inptr = input; - inptr2 = input; - endoffile = 0; // На начале файла - return(0); -} - -// ---- Обработка макроса -Macros() -byte holdcha; -byte s[STRLEN],s2[STRLEN]; -{ - IF(makemapfile){ - fprint(mapfile,#string); - fprint(mapfile,"\n"); - } - holdcha=cha2; - $PUSH linenum2,inptr2,number,tok2,tok,input,inptr,currmod, - linenumber,endoffile,displaytokerrors; - lstrcpyA(#s,#string); - lstrcpyA(#s2,#string2); - input=#s; - inptr=input; - inptr2=input; - endoffile=0; // На начале файла - NextChar(); - cha2=cha; - inptr2=inptr; - linenum2 = 1; - NextTok(); - for(;;){ - IF(tok==tk_eof)BREAK; - DoCommand(); - } - lstrcpyA(#string,#s); - lstrcpyA(#string2,#s2); - $POP displaytokerrors,endoffile,linenumber,currmod,inptr,input,tok,tok2, - number,inptr2,linenum2; - cha2=holdcha; -} - -// ---- Очистка списка локальных переменных -KillLocals() -dword ptr1,ptr2; -{ - ptr2=locallist; - WHILE( ptr2 != NULL ){ - ptr1=ptr2; - IF( DSDWORD[EAX+localtok]==tk_locallabel) // Проверка на незакрытые метки - localunresolved(EAX+localid); - EAX=ptr2; - ptr2=DSDWORD[EAX+localnext]; - GlobalFree(ptr1); - } - locallist = NULL; - paramsize = 0; - localsize = 0; -} - -// ---- Завершение тела процедуры -LeaveProc() -{ - IF(localsize > 0)Asm("leave"); - ELSE{ - IF(paramsize > 0)Asm("pop ebp"); - } - IF( current_proc_type == cpt_far ){ - IF(paramsize == 0)EAX="retf"; - ELSE{ - wsprintfA(#mapstr,"retf %d;",paramsize); - EAX=#mapstr; - } - } - ELSE{ - IF(paramsize == 0)EAX="ret"; - ELSE{ - wsprintfA(#mapstr,"ret %d;",paramsize); - EAX=#mapstr; - } - } - Asm(EAX); -} - -// ---- Чтение очередного символа из входного буфера -NextChar() -{ - ESI> 0)Asm("push ebp;mov ebp,esp"); - IF( tok != tk_openbrace )DeclareLocals(); - DoBlock(); // Обработка тела процедуры { ... } - LeaveProc(); - KillLocals(); -} - -// ---- Запись двойного слова по адресу -SetDword(dword ptr, value) -{ - EDI> "); -} - -// ---- -expected(dword ch) -byte hstr[80]; -{ - wsprintfA(#hstr,"'%c' expected",ch); - preerror(#hstr); -} - -// ---- -expectederror(dword str) -byte hstr[80]; -{ - IF(displaytokerrors){ - wsprintfA(#hstr,"'%s' expected",str); - preerror(#hstr); - } -} - -// ---- Проверка текущего token на заданный тип -expecting(dword want) -{ - if(want!=tok){ - IF(want==tk_closebracket) expected(')'); - else IF(want==tk_openbracket) expected('('); - ELSE IF(want==tk_semicolon) expected(';'); - ELSE IF(want==tk_colon) expected(':'); - ELSE IF(want==tk_openblock) expected('['); - ELSE IF(want==tk_closeblock) expected(']'); - ELSE IF(want==tk_openbrace) expected('{'); - ELSE IF(want==tk_closebrace) expected('}'); - ELSE IF(want==tk_comma) expected(','); - ELSE preerror("expecting a different token"); - } - NextTok(); -} - -// ---- -/*idalreadydefined() -byte holdstr[80]; -{ - wsprintfA(#holdstr,"identifier %s already defined",#string); - preerror(#holdstr); - NextTok(); -} */ - -// ---- -idexpected() -{ - preerror("undefined 'identifier' expected"); -} - -// ---- Внутренняя ошибка компилятора -internalerror(dword str) -{ - error++; - wsprintfA(#mapstr,"%s(%d)#%d> *** SERIOUS COMPILER INTERNAL ERROR ***\n>%s.\n", - #currentfilename,linenumber,error,str); - WRITESTR(#mapstr); - wsprintfA(#mapstr,"STRING:%s\n",#string); - WRITESTR(#mapstr); - wsprintfA(#mapstr,"TOK:%d\tPOST:%d\tnumber:%ld\n",tok,post,number); - WRITESTR(#mapstr); - wsprintfA(#mapstr,"STRING2:%s\n",#string2); - WRITESTR(#mapstr); - wsprintfA(#mapstr,"TOK2:%d\tPOST2:%d\tnumber2:%ld\n",tok2,post2,number2); - WRITESTR(#mapstr); - WRITESTR("Oh no.\n"); - IF(makemapfile)CloseHandle(mapfile); - ExitProcess(e_internalerror); -} - -// ---- -localunresolved(dword str) -byte holdstr[80]; -{ - wsprintfA(#holdstr,"local jump label '%s' unresolved",str); - preerror(#holdstr); -} - -// ---- -maxwordpostserror () -{ - preerror("maximum number of word post location references exceeded"); -} - -// ---- -/*notyet() -{ - preerror("specified syntax not handled in this version!!!"); -} */ -// ---- -numexpected() -{ - preerror("'number' expected"); -} - -// ---- -operatorexpected () -{ - preerror("operator identifier expected"); -} -// ---- -outofmemory() -{ - preerror("Compiler out of memory"); - IF( makemapfile )CloseHandle(mapfile); - ExitProcess(e_outofmemory); -} - -// ---- -outofmemory2() -{ - errmsg(); - WRITESTR("Not enough memory for the compiler's buffers.\n"); - ExitProcess(e_outofmemory ); -} - -// ---- Ошибка в текущей строке: показ номера строки и имени файла -preerror(dword str) -{ - IF(error < maxerrors){ - error++; - wsprintfA(#mapstr,"%s (%d)#%d> %s.\n",#currentfilename,linenumber,error,str); - WRITESTR(#mapstr); - IF(makemapfile)fprint(mapfile,#mapstr); - } - ELSE toomanyerrors(); -} - -// ---- -/*regnameerror() -{ - preerror("register name cannot be used as an identifier"); - NextTok(); -} */ - -// ---- Требуется строка -stringexpected() -{ - preerror("'string' expected"); -} - -// ---- Недопустимый операнд для swap -swaperror () -{ - preerror("invalid or incompatable swap item"); -} - -// ---- Предельное число ошибок - выход -toomanyerrors() -{ - IF( makemapfile )CloseHandle(mapfile); - ExitProcess( e_toomanyerrors ); -} - -// ---- -unabletoopen(dword str) -byte hstr[80]; -{ - wsprintfA(#hstr,"unable to open file '%s'",str); - preerror(#hstr); -} - -// ---- -undefinederror() -byte holdstr[80]; -{ - wsprintfA(#holdstr,"'%s' undefined",#string); - preerror(holdstr); -} - -// ---- -unexpectedeof() -{ - preerror("unexpected END OF FILE"); -} -// ---- -warning(dword str) -{ - wsprintfA(#mapstr,"%s (%d)Warning> %s.\n",#currentfilename,linenumber,str); - WRITESTR(#mapstr); - IF(makemapfile)fprint(mapfile,#mapstr); -} -/* -void TestProc() -char buf[20]; -{ - $pushad - wsprintfA(#buf,"%08X\n",SSDWORD[EBP+4]); - WRITESTR(#buf); - $popad -} */ diff --git a/programs/develop/c--/trunk/ORIGINAL_LICENSE.txt b/programs/develop/c--/trunk/ORIGINAL_LICENSE.txt deleted file mode 100644 index 4a7c23e17c..0000000000 --- a/programs/develop/c--/trunk/ORIGINAL_LICENSE.txt +++ /dev/null @@ -1,152 +0,0 @@ -INTRO TO SPHINX C-- (updated 28 Oct 1996) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Hello, and welcome to SPHINX C--. C-- is a language I (Peter Cellik) -created, it is a half way point between C and Assembly. The main thought -behind C-- is to create very small, and hopefully fast programs. The output -efficiency is close to assembly with the source file being similar to C and -thus more readable than assembly source. C-- can be used as a stand alone -language, or, via the use of Microsoft compatible OBJ output, be used within -another language such as C++ or Borland Pascal. - -This is the final release of C--! It has been over a year since I have made -any changes to C--, so I have decided its time to release it all to the -public domain. I have enjoyed your responses over the years and I look -forward to more. I have had replies from over 25 different countries. -Thank you everyone for saying hello. Sorry if I did not reply, sometimes -there just isn't time. - -The file is C--FINAL.ZIP. It should contain the compiler, the examples and -also the source code. - - -REQUIREMENTS: -~~~~~~~~~~~~~ - System Requirements: - - 8086 or higher CPU computer - - DOS 3.0 or greater - - 512K RAM or greater - - Keyboard (I should hope) - - a hard drive will really speed things up, though C-- can even run off a - floppy if you are not in a hurry - - a mouse may assist navigation through the C-- Work Bench, but the - keyboard can be used instead - - some of the example files require VGA display, if you do not have VGA - you are missing out on life - - Programmer Requirements (uh-oh): - - Brain (a good one too) - - Reasonable understanding of C or similar high level language - - Some 8086 or higher assembly knowledge, the more the better - - -FILE LIST: -~~~~~~~~~~ -The following files should be included in the C--C????.ZIP package: - -.\C-- EXE // The SPHINX C-- Compiler -.\C-- OVL // File required by C--.EXE -.\WB COM // C-- Work Bench Driver -.\WB EXE // C-- Work Bench Main Program -.\C--INFO DOC // Info on the C-- Programming Language -.\C--ASM DOC // Info on C-- Inline Assembly Language -.\STAKPROC DOC // Info on C-- stack procedures -.\REGPROCS DOC // Info on C-- REG procedures and macros -.\WBHELP DOC // Info on using the C-- Work Bench -.\ALLPROCS DOC // List of all stack and REG procedures and macros -.\???????? H-- // Some C-- header files -.\README DOC // This file your reading -.\examples\GUS\*.* // Gravis Ultra Sound example programs -.\examples\OBJ\*.* // OBJ file output example programs -.\examples\OTHER\*.* // Misc. example programs -.\examples\ROCK\*.* // VGA game example program -.\examples\SBLASTER\*.* // Sound blaster example programs -.\examples\SIMPLE\*.* // Small and simple example programs -.\examples\SYSTEM\*.* // System detection example programs -.\examples\TSR\*.* // Terminate and Stay Resident example programs -.\examples\VGA\*.* // VGA example programs -.\examples\stuff\*.* // some personal examples -.\examples\HISTORY.DOC // Revision history of this example package -.\source\*.* // Source for SPHINX C-- Compiler and Work Bench - -NOTE: I do not take credit (or blame) for EURO_MOD.EXE, it is supplied as a - usefully utility which can be accessed via a C-- header file. It is - free and, as far as I understand, can be used and distributed by - anyone for anyone. - - - -HOW TO START: -~~~~~~~~~~~~~ -UnZIP the C--FINAL.ZIP package using the '-d' option. - -Next, set the 'C--' environmental variable to the full path of the directory -you unzipped into. C-- uses the 'C--' environmental variable to find the -compiler, help files and include files. For example, if you unzipped C-- -into the directory 'C:\C--', then you would type: - - SET C--=C:\C-- - -You may wish to add the above line to your 'AUTOEXEC.BAT'. - -You may then type WB at the DOS prompt to start the C-- Work Bench. Take a -look at some the *.C-- example files. Press F3 to load and F5 to compile and -run. - -Be sure to be in the same directory as the source file(s) for the *.C-- file -may need to load some other files, such as palettes and bitmaps. Use the -'Change Dir...' command in the 'File' menu to change directories. - -After you get a taste of what it can do, take a look at the file 'C--INFO.DOC' -for information on how to program in C--. 'C--INFO.DOC' can be viewed in the -C-- Work Bench by pressing or selecting 'Main General Help' from -the 'Help' menu. - - -THE PRICE: -~~~~~~~~~~ -This version of C-- is GREENWARE, and you are free to use it so long as you -make an effort everyday to help out the environment. A few ideas: - - use only recycled computer paper - - be sure to recycle the computer paper after you use it - - use public transport - - sell that 80 cylinder car of yours and buy a small 4 cylinder, or - better yet, buy a motorbike - - support Green Peace - - REDUCE-REUSE-recycle - - stop smoking - - ride a bike to work or school - - don't buy products that are harmful to the environment - - stop using weed killers on your lawn - - support Friends of the Earth - - recycle your cans - - don't buy products that have lots of extra packaging - - use a fax modem instead of a paper fax machine - - reuse your plastic bags - - (you get the idea) - - -DISCLAIMER: -~~~~~~~~~~~ -I accept no responsibility for any damage or loss of time, hardware, sanity, -software or data caused by this product or programs made with it. So there! - - -FINAL NOTES: -~~~~~~~~~~~~ -Any programs you make with C-- you may do with as you wish. I would greatly -appreciate any feedback you can give me. Just say hello, or send me some -cool stuff. Send me your comments, maybe even some code you have written, -I would like them very much. - -I can be contacted at: PETER SPHINX CELLIK - RR#2 SITE 33 C11 - GABRIOLA ISLAND B.C. - V0R 1X0 - CANADA - -Current E-mail Address: cellik@sfu.ca - -Hope to hear from you soon. - -/* end of README.DOC */ diff --git a/programs/develop/c--/trunk/data.h-- b/programs/develop/c--/trunk/data.h-- deleted file mode 100644 index da298b2478..0000000000 --- a/programs/develop/c--/trunk/data.h-- +++ /dev/null @@ -1,157 +0,0 @@ -//===== Глобальные переменные -// ---- Информация по tokens -dword tok=0; -dword type=0; -dword src=0; -dword post=0; -dword number=0; -byte string[STRLEN]=0; -dword tok2=0; -dword type2=0; -dword src2=0; -dword post2=0; -dword number2=0; -dword modline=0; -byte string2[STRLEN]=0; -// ---- Буфера управляющие флаги -dword currmod=0; // Номер текущего файла -dword displaytokerrors=1;// Флаг вывода сообщен й об ош бке -dword error=0; // Содержит номер текущей ошибк -dword maxerrors = 16; // Предел по количеству ошибок -dword makemapfile=0; // Флаг генерац и MAP-файла -dword dbg=0; // Флаг генерац и TDS-файла для TD32 -dword dbginfo=0; // Указатель на буфер dbg информацией (см.описание в enum dbg_...) -dword dbgs=0; // Текущий указатель в dbginfo -dword input=0; // Указатель на начало динамического буфера с входным файлом -dword inptr=0; // Указатель на текущ символ в буфере input -dword inptr2=0; // Копия inptr -dword endoffile=0; // Флаг конца файла -dword totallines=1; // Общее количество откомпилированных строк -dword linenumber=0; // Номер текущей строки -dword linenum2=0; // Номер следующей строки -dword list=0; // Флаг выдачи листинга -dword label=0; // Сквозной номер для локальных меток -dword mapfile=0; // Handle для MAP файла -dword module=0; // Счетчик откомпилированных модулей -dword outptr=0; // Индекс в output -dword output=0; // Указатель на буфер с кодом -dword localsize=0; // Размер стека под локальными переменными -dword posttype=0; // Указатель на тип POST -dword postloc=0; // Указатель на положение в output -dword postnum=0; // Указатель на значение по postloc -dword posts=0; // Номер текущей записи в posttype, postloc и postnum -dword postsize=0; // Суммарный размер всех post-переменных -dword poststrptr=MAXDATA-1; // Индекс для вывода post-строк -dword procedure_start=0;// Адрес начала процедуры -dword runfilesize=0; -dword startptr=0; // Указатель на main() -dword treestart=0; // Указатель на начало списка идентификаторов -dword treeptr=0; // Указатель на текущу запись в списке идент каторов -dword locallist = NULL; // Указатель на начало списка локальных переменных -dword localptr=NULL; // Указатель на текущую запись в списке локальных -dword DLLcount=0; // Счетчик импортированных DLL -dword APIcount=0; // Счетчик используемых API -dword importFlag=0; // Флаг импорта из DLL -dword DLLlist[MAXDLLS]; -byte currentfilename[FILENAMESIZE] = 0; -byte inputfile[FILENAMESIZE]=0; -byte rawfilename[FILENAMESIZE]=0; -byte mapstr[120]=0; -// ---- DOS&PE headers -word exeheader[34]={ - 0x5A4D,0x40,1,0,2,0,0xFFFF,0, - 0,0,0,0,0x40,0,0,0, - 0xC88C,0xD88E,0x0FBA,0xB400,0xCD09,0xB821,0x4C00,0x21CD, - 0x6957,0x336E,0x2032,0x6E6F,0x796C,0x2421,0x40,0, - 0x4550,0}; -// PE Header -//unsigned dword PEsign = 0x4550; -word PEmachine=0x14C; // target machine = Intel 386 -word PEnSections=1; // XAC - only .text!!! number of sections in Sections table -word PEDate=0; -word PEtime=0; -dword PEpSymbolTable=0; // Offset within COFF file of the symbol table -dword PEnSymbols=0; // number of entries in the symbol table -word PEOptHeaderSize=0xE0; // Size of optional header -word PECharacteristics=0x30E; //0x30E 32-bit+... -// Optional header (only in EX image) -word OptMagic=0x10B; // normal executable -byte OptLmajor=2; // Linker major version number -byte OptLminor=0x37; // Linker minor version number -dword OptCodeSize=0; // Size of the code section -dword OptInitDataSize=0; // Size of the initialized data section -dword OptUninitDataSize=0;// Size of the uninitialized data section (BSS) -dword OptEntryPointRVA=0x1000;// Address of entry point, relative to image base -dword OptBaseOfCode=0x1000;// Address realtive to image base -dword OptBaseOfData=0;//Address realtive to image base -dword OptImageBase=0x00400000;// Preferred address of first byte of image -dword OptSectionAlignment=0x1000; -dword OptFileAlignment=0x200; -word OptOSmajor=1; -word OptOSminor=0; -dword OptUserVersion=0; -word OptSubSysMajor=4; -word OptSubSysMinor=0; -dword OptReserved=0; -dword OptImageSize=0x0; // Size of image, including all headers -dword OptHeaderSize=0x200; //DOSheader+PEheader+ObjectTable -dword OptFileChecksum=0; // Image file checksum -word OptSubSystem=3; // 2-GUI; 3-console -word OptDLLflag=0; -dword OptStackReserveSize=0x100000; -dword OptStackCommitSixe=0x1000; -dword OptHeapReserveSize=0x100000; -dword OptHeapCommitSize=0x1000; -dword OptLoaderSize=0; -dword OptNumOfDataDirectories=16; -// Optional header Data Directories -dword OptExportTableAdr=0; -dword OptExportTableSize=0; -dword OptImportTableAdr=0; -dword OptImportTableSize=0; -dword OptResourceTableAdr=0; -dword OptResourceTablesize=0; -dword OptExceptionTableAdr=0; -dword OptExceptionTableSize=0; -dword OptSecurityTableAdr=0; -dword OptSecurityTableSize=0; -dword OptBaseRelocationTableAdr=0; -dword OptBaseRelocationTableSize=0; -dword OptDebugAdr=0; -dword OptDebugSize=0; -dword OptCopyrightAdr=0; -dword OptCopyrightSize=0; -dword OptGlobalPtrAdr=0; -dword OptGlobalPtrSize=0; -dword OptTLStableAdr=0; -dword OptTLStablesize=0; -dword OptLoadConfigTableAdr=0; -dword OptLoadConfigTableSize=0; -dword OptReserved2[10]={0,0,0,0,0,0,0,0,0,0}; -// Sections Table -// TEXT section header -byte TxtSectionName[8]=".text"; -dword TxtVirtualSize=0; -dword TxtRVAoffset=0x1000; -dword TxtSizeOfRawData=0; -dword TxtPointerToRawData=0x200; -dword TxtPointerToRelocs=0; -dword TxtPointerToLinenumbers=0; -word TxtNumberOfRelocs=0; -word TxtNumberOfLinenumbers=0; -dword TxtSectionFlags=0xE00000E0; // can be executed + contain executable code -// ---- Неиниц руемые данные -dword stdout; // Handle to stdout -byte cha,cha2; -dword numberofids; -dword current_proc_type; // Тип текущей процедуры (cpt_near, cpt_far) -dword returntype; // Тип возвращаемого значения (void, byte, word, ...) -dword paramsize; -dword relation; -dword startlabel,endlabel; -byte modules[MAXMDL*FILENAMESIZE]; -dword St_Mnemonics[26]; -dword St_Registers[26]; -dword St_Directives[26]; -dword St_Sizes[26]; -byte Buffer16[64]; // Буфер для сортировк строк diff --git a/programs/develop/c--/trunk/directiv.h-- b/programs/develop/c--/trunk/directiv.h-- deleted file mode 100644 index 9d67e7d086..0000000000 --- a/programs/develop/c--/trunk/directiv.h-- +++ /dev/null @@ -1,986 +0,0 @@ -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 -}; diff --git a/programs/develop/c--/trunk/enums.h-- b/programs/develop/c--/trunk/enums.h-- deleted file mode 100644 index 1600fccbe8..0000000000 --- a/programs/develop/c--/trunk/enums.h-- +++ /dev/null @@ -1,109 +0,0 @@ -//===== Глобальные константы -#define STD_INPUT_HANDLE -10 -#define STD_OUTPUT_HANDLE -11 -#define STD_ERROR_HANDLE -12 -#define CREATE_NEW 1 -#define CREATE_ALWAYS 2 -#define OPEN_EXISTING 3 -#define OPEN_ALWAYS 4 -#define TRUNCATE_EXISTING 5 -// ---- -#define GENERIC_READ 0x80000000 -#define GENERIC_WRITE 0x40000000 -#define GENERIC_EXECUTE 0x20000000 -#define GENERIC_ALL 0x10000000 -// ---- Константы компилятора -#define _END 0x1B -#define FILENAMESIZE 80 -#define IDLENGTH 65 // Длина имени идентификатора, включая NULL-терминатор -#define MAXDATA 512000 // Размер буферов под код и данные -#define MAXDBGS 50000 // Размер буферов под отладочну информацию -#define MAXDLLS 100 -#define MAXINPUT 512000 // Максимальны размер входного файла -#define MAXMDL 100 // Максимальное число includes -#define MAXPOSTS 150000 // Размер буферов под POST обработку -#define NULL 0 -#define SORTSIZE 20 -#define STRLEN 1000 // Длина буфера под token -// ------------------------------------------ -//===== Нумерованные константы -// ---- Коды возврата -enum{ e_ok, e_outofmemory, e_cannotopeninput, e_toomanyerrors, - e_internalerror, e_noinputspecified, e_unknowncommandline, - e_extract, e_cannotopenmapfile, e_someerrors }; -// ---- Коды tokens tk_xxxx -enum{ -tk_eof,tk_number,tk_string,tk_var, -tk_id, -tk_db,tk_dw,tk_dd,tk_dq, // Типы переменных -tk_byte,tk_char,tk_word,tk_short, -tk_dword,tk_int, -tk_enum, // Нумерованные константы -tk_struc, // Определение структуры -tk_if,tk_else,tk_endif, // Условная компиляция -tk_include,tk_define, // Включение фа ла//Определение константы -tk_import, // Импорт из DLL -tk_map, // Генерация MAP-файла -tk_debug, // Генерация отладочной информации -tk_list, // Выдача ASM-листинга -tk_dll, // Генерация DLL-файла -tk_loop,tk_return,tk_do, -tk_while,tk_void, -tk_continue,tk_break, -tk_docase,tk_case,tk_default, -tk_carryflag,tk_extract,tk_FALSE,tk_from, -tk_notcarryflag,tk_notoverflow,tk_overflow,tk_TRUE, -tk_zeroflag,tk_notzeroflag, -tk_assign,tk_swap, -tk_minus,tk_plus, -tk_minusminus,tk_plusplus,tk_mult,tk_div,tk_mod, -tk_multminus,tk_divminus,tk_modminus,tk_rr,tk_ll, -tk_rrminus, -tk_llminus, -tk_minusequals,tk_plusequals,tk_rrequals,tk_llequals, -tk_or,tk_and,tk_xor,tk_not, -tk_orminus, -tk_andminus,tk_xorminus, -tk_orequals,tk_andequals,tk_xorequals, -tk_equalto, -tk_notequal,tk_greater,tk_greaterequal,tk_less, -tk_lessequal, -tk_oror,tk_andand,tk_openbrace,tk_closebrace, -tk_openbracket,tk_closebracket,tk_openblock,tk_closeblock, -tk_colon,tk_semicolon,tk_comma,tk_period, -tk_dollar,tk_question,tk_tilda, -tk_reg,tk_controlreg,tk_debugreg,tk_testreg,tk_seg, -tk_undefproc,tk_proc, -tk_postnumber, -tk_local,tk_locallabel,tk_param,tk_locnumber, -tk_DLL,tk_API,tk_directive,tk_command,tk_mnemonics, -tokens -}; -// ---- Кодировка типа процедур -enum{ cpt_near, cpt_far }; -// ---- Кодировка POST записей -enum { POST_CALL=1, POST_API, POST_DATA, POST_LOC, POST_STR }; -// ---- Описание структуры в dbginfo: dbg_... -enum{ dbg_mod=0, // Номер модуля - dbg_line=4, // Номер строк в модуле - dbg_loc=8, // Позиция в EXE-файле - dbg_size=12}; // размер структуры -// ---- Описание структуры idrec -enum{ left=0, // Указатель на idrec - right=4, // Указатель на idrec - recid=8, // Имя идентификатора - newid=recid+4, // Указатель на алиас для recid - rectok=newid+4, // Номер token - rectype=rectok+4, // Тип token: void, byte, char, word, ... - recsrc=rectype+4, // Исходный текст - recpost=recsrc+4, // Флаг POST переменной - recnumber=recpost+4, // Значение или offset в recsrc - recmodline=recnumber+4,// Номер модуля и строки - recsize=recnumber+4};// размер структуры -// ---- Описание структуры localrec -enum{ localnext=0, // Указатель на следующую localrec - localid=4, // Имя локально переменной - localtok=localid+IDLENGTH,// Значение token - localtype=localtok+4, // тип переменной - localnumber=localtype+4, // Позиция в стеке - local_size=localnumber+4}; // Размер структуры diff --git a/programs/develop/c--/trunk/examples/docase.c- b/programs/develop/c--/trunk/examples/docase.c- deleted file mode 100644 index d4240a3ba6..0000000000 --- a/programs/develop/c--/trunk/examples/docase.c- +++ /dev/null @@ -1,17 +0,0 @@ -#map -#debug -#list -main() // execution always starts at main () -{ -docase{ - EBX+=80; - case(ECX==10) -//#list - EBX=10; - case(EBX<5){ - ECX=5; continue;} - default - EDX+=8; - } -EAX=9; -} \ No newline at end of file diff --git a/programs/develop/c--/trunk/examples/docase.map b/programs/develop/c--/trunk/examples/docase.map deleted file mode 100644 index c5dd268ad7..0000000000 --- a/programs/develop/c--/trunk/examples/docase.map +++ /dev/null @@ -1,71 +0,0 @@ -MAP FILE FOR DOCASE.EXE - -{ -docase{ - EBX+=80; - // @L0: - // add EBX,80 - case(ECX==10) - // mov eax,ECX - // cmp eax,0xa - // sete al - // movzx eax,al -//#list - // test eax,eax;jz @L2 - EBX=10; - // mov EBX,10 - case(EBX<5){ - // jmp @L1 - // @L2: - // mov eax,EBX - // cmp eax,0x5 - // setl al - // movzx eax,al - // test eax,eax;jz @L3 - ECX=5; continue;} - // mov ECX,5 - // jmp @L0 - default - EDX+=8; - // jmp @L1 - // @L3: - // add EDX,8 - } -EAX=9; - // @L1: - // mov EAX,9 -} - // ret -Compile all sources - -ALL GLOBAL IDENTIFIERS LIST: -tok type number post IDENTIFIER -104 1Fh 401000h 0h main -File:DOCASE.C-, line=4: -() // execution always starts at main () -{ -docase{ - EBX+=80; - case(ECX==10) -//#list - EBX=10; - case(EBX<5){ - ECX=5; continue;} - default - EDX+=8; - } -EAX=9; -} - - 1 Unique Global Identifiers. - -GLOBAL CONSTANT IDENTIFIER LIST: - - 0 Unique Global Constant Value Identifiers. - -Component Sizes: -Code:128 bytes, Post: 0 bytes -Run file size: 128 bytes - -END OF MAP FILE FOR DOCASE.EXE - diff --git a/programs/develop/c--/trunk/exe.h-- b/programs/develop/c--/trunk/exe.h-- deleted file mode 100644 index c82b972601..0000000000 --- a/programs/develop/c--/trunk/exe.h-- +++ /dev/null @@ -1,145 +0,0 @@ -// ---- Формирование IMPORT секции -void DoLink() -dword i,j,DirTable,AddrTable,dllName,apiName,byName,hold; -dword dll,api; -{ - OptImportTableAdr=outptr-output; - DirTable=outptr; - if(APIcount==0){ - OUTDWORD(outptr -output + OptBaseOfCode + 4); - OUTDWORD(0x80000001); - OUTDWORD(0); - OUTDWORD(DirTable-output+40+OptBaseOfCode); - OUTDWORD(outptr-output + OptBaseOfCode - 12); - DirTable=outptr; - outptr = outptr + 20; - OUTDWORD('resu'); - OUTDWORD('d.23'); - OUTDWORD('ll'); -// OUTDWORD(0x72657375); OUTDWORD(0x642E3233); OUTDWORD(0x6C6C); - apiName=outptr; - } - else { - EAX=DLLcount+1*20; - outptr+=EAX; // на начало LookupTables - i=0; - while(i= 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}; diff --git a/programs/develop/c--/trunk/opcodesc.h-- b/programs/develop/c--/trunk/opcodesc.h-- deleted file mode 100644 index 613f785e74..0000000000 --- a/programs/develop/c--/trunk/opcodesc.h-- +++ /dev/null @@ -1,591 +0,0 @@ -//CODE GENERATION DESCRIPTORS -// ========================= -// >>> DESCRIPTION CODES <<< -// ========================= - -//T_: -// DB -// [DB ] -// [DB ] -// DB -// DB -// DB 0 -//OR DB _END //IF THERE'RE NO MORE INFO ABOUT THIS MNEMONIC - -// OPERATION SIZE CODES -enum { _B, //OPERATION MAY BE OF SIZE BYTE,WORD OR DWORD SEIN. THE OPCODE'S - // W BIT INDICATES IF IT'S A BYTE OR WORD OPERATION. - // FOR DWORD OPERATIONS, THE W BIT MUST BE TRUE (WORD OPERATION) - // AND THE RAND:PREFIX MUST BE GENERATED. - _W, //OPERATION SIZE MAY BE WORD OR DWORD. - _D, //OPERATION MAY ONLY BE DWORD. - WB, //1. OPERAND WORD, 2. OPERAND BYTE - _DW, //1. OPERAND DWORD, 2. OPERAND WORD - BW, //1. OPERAND BYTE, 2. OPERAND WORD - NB, //ONLY BYTE SIZE. - _OW, //ONLY WORD SIZE. - _OD, // Only DWORD size - AF}; //ONLY ABSOLUTE FAR 32/48 BIT ADDRESS - -#define _JB 1 //OPERAND IS A JUMP - DESTINATION +/-128 -#define _JW 2 //OPERAND IS A JUMP - DESTINATION +/-32678 - -// 0-2 = OPERATION SIZE CODE -// 3-4 = # OF OPERANDS NEEDED. - -// # OF OPERANDS -#define OL0 0 -#define OL1 0o10 -#define OL2 0o20 -#define OL3 0o30 - -#define OLBITS 0o30 //MASKS FOR # OF OPERANDS. -#define NOLBITS 0o347 -#define TRANSBITS 0o7 //MASKS FOR OPERATION SIZE CODES. -#define NTRANSBITS 0o370 - -// IF OL1, USE THIS OPERAND TYPES: -#define SOJ 0b00000000 //JUMP -#define SOE 0b00100000 //EA -#define SOR 0b01000000 //REG -#define SOC 0b01100000 //CONST -#define SO3 0b10000000 //_3 -#define SOS 0b10100000 //SREG -#define SOM 0b11000000 //EA-MEMORY-POINTER -#define SOO 0b11100000 //THERE IS INFORMATION USING THE OPERAND SIZE CODE BITS. -#define SOO_FS 0o340 //FS-REGISTER -#define SOO_GS 0o341 //GS-REGISTER -#define SOO_AF 0o342 //ABSOLUTE ADRESS -#define SOO_CC 0o343 //SIGNED BYTE -#define OPBITS 0b11100000 - -// IF OL2, USE THOSE INSTEAD: -// 00000000B //DIRECT DESCRIPTOR - //AR,CO -#define ERO 0b00100000 //FIXED EA,REG ORDER -#define REO 0b01000000 //FIXED REG,EA ORDER -#define DER 0b01100000 //EA,REG OR REG,EA DEFINED BY A D-BIT -#define ECO 0b10000000 //EA,CONSTANT// SIZE DEFINED BY W-BIT -#define ECCO 0b10100000 //EA,CC -#define RCO 0b11000000 //REG,CONSTANT// SIZE DEFINED BY W-BIT -#define EAO 0b11100000 //EA,? // SECOND OPERAND DESCRIBED BY OLD DESCIPTORS - //?=_1,rCL,CO - -// OPERAND TYPE CODES -enum { R, //GENERAL REGISTER - E, //EFFEKTIVE ADRESS - CO, //CONSTANT - _SR, //SEGMENT REGISTER - SYSR, //SYSTEM REGISTER - _DR, //DEBUG REGISTER - _TR, //TASK REGISTER - _CR, //CONTROL REGISTER - _CR4, // - _AF, //ABSOLUTE 32/48 BIT FAR ADDRESS - AR=11, //AX/AL REGISTER, INDICATED BY OPERATION SIZE - _1}; //CONSTANT VALUE 1 - -// IF OL3, USE THIS: -// INSTRUCTION WITH THREE OPERANDS ARE ALWAYS OF SIZE WORD. -// THE FOLLOWING CODES DESCRIBE THE 3RD OPERAND. -enum { CB3, //BYTE CONSTANT - CW3, //WORD CONSTANT - CC3, //SBYTE CONSTANT - CL3}; //CL REGISTER - -// OPCODE DESCRIPTORS -enum{ O=1, //OPCODE IS A BYTE - OW, //OPCODE IS A WORD - OS, //OPCODE IS A BYTE PLUS A SECOND BYTE THAT IS DESCRIBED BY AN - //OCTAL STRING. - S, //OCTAL STRING FOLLOWS FOR OPCODE - XRM, //MODRM BYTE - XPM, //MODRM MIT P-FLAG (GRUPPE VON ARITHMETIC INSTRUCTIONS) - XSM, //MODRM MIT SEGMENTREGISTER - X0M,X1M,X2M,X3M,X4M,X5M,X6M,X7M //MODRM WITH CONSTANT R DIGIT - }; - -byte OVERRIDETAB={0o46,0o56,0o66,0o76,0o144,0o145}; -// ---- Кодировка регистров -enum{ rAL ,rCL ,rDL ,rBL ,rAH ,rCH ,rDH ,rBH, // 0-7 byte regs - rAX ,rCX ,rDX ,rBX ,rSP ,rBP ,rSI ,rDI, // 8-15 16-bit word regs - rEAX,rECX,rEDX,rEBX,rESP,rEBP,rESI,rEDI,// 16-23 32-bit regs - rCR0,rCR1,rCR2,rCR3,rCR4,rCR5,rCR6,rCR7,// 24-31 control regs - rDR0,rDR1,rDR2,rDR3,rDR4,rDR5,rDR6,rDR7,// 32-39 debug regs - rTR0,rTR1,rTR2,rTR3,rTR4,rTR5,rTR6,rTR7,// 40-47 test regs - rES,rCS,rSS,rDS, rFS,rGS}; // 48-53 seg regs -byte Registers={ - "AL","CL","DL","BL","AH","CH","DH","BH", - "AX","CX","DX","BX","SP","BP","SI","DI", - "EAX","ECX","EDX","EBX","ESP","EBP","ESI","EDI", - "CR0","CR1","CR2","CR3","CR4","CR5","CR6","CR7", - "DR0","DR1","DR2","DR3","DR4","DR5","DR6","DR7", - "TR0","TR1","TR2","TR3","TR4","TR5","TR6","TR7", - "ES","CS","SS","DS","FS","GS",_END}; -byte Sizes={"BYTE","WORD","DWORD",_END}; - -// ---- Описания менмоник -byte PCOMMANDS1={ - 0, //P FLAG STARTS AT 0 - _B+OL2+EAO,AR,CO,S,"0P4", - _B+OL2+DER,S,'0','P','0',XRM,0, - _W+OL2+ECCO,O,0o203,XPM,0, - _B+OL2+ECO,O,0o200,XPM,_END}; - -byte PCOMMANDS2={ - 4, //P FLAG STARTS AT 4 - _B+OL1+SOE,O,0xF6,XPM,_END}; -byte PCOMMANDS3= 0; //P FLAG STARTS AT 0 -byte PCOMMANDS3_={ - _B+OL2+EAO,-1,_1,O,0xD0,XPM,0, - _B+OL2+EAO,-1,rCL,O,0xD2,XPM,0, - _B+OL2+ECCO,O,0xC0,XPM,_END}; - -byte PCOMMANDS4={ - 4, //P FLAG STARTS AT 4 - _W+OL2+ERO,OS,0xF,'2','P','3',XRM,0, - WB+OL2+ECO,OW,0xF,0o272,XPM,_END}; -// Однобайтовые инструкции -byte T_DAA={ O,0o47,_END}; -byte T_DAS={ O,0o57,_END}; -byte T_AAA={ O,0o67,_END}; -byte T_AAD={ OW,0o325,0o12,_END}; -byte T_AAM={ OW,0o324,0o12,_END}; -byte T_AAS={ O,0o77,_END}; -byte T_CWDE={ O,0o230,_END}; -byte T_CBW={ OW,0x66,0o230,_END}; -byte T_CDQ={ O,0o231,_END}; -byte T_CWD={ OW,0x66,0o231,_END}; -byte T_XLATB={ O,0o327,_END}; -byte T_NOP={ O,0o220,_END}; -byte T_WAIT={ O,0o233,_END}; -byte T_LOCK={ O,0o360,_END}; -byte T_HLT={ O,0o364,_END}; -byte T_INTO={ O,0o316,_END}; -byte T_IRET={ O,0o317,_END}; -byte T_POPFD={ O,0o235,_END}; -byte T_POPF={ OW,0x66,0o235,_END}; -byte T_PUSHFD={ O,0o234,_END}; -byte T_PUSHF={ OW,0x66,0o234,_END}; //PUSHF / (#) PUSHFD -byte T_SAHF={ O,0o236,_END}; -byte T_LAHF={ O,0o237,_END}; -byte T_CMC={ O,0o365,_END}; -byte T_CLC={ O,0o370,_END}; -byte T_STC={ O,0o371,_END}; -byte T_CLI={ O,0o372,_END}; -byte T_STI={ O,0o373,_END}; -byte T_CLD={ O,0o374,_END}; -byte T_STD={ O,0o375,_END}; -byte T_PUSHAD={ O,0o140,_END}; -byte T_PUSHA={ OW,0x66,0o140,_END}; -byte T_POPAD={ O,0o141,_END}; -byte T_POPA={ OW,0x66,0o141,_END}; -byte T_INSB={ O,0o154,_END}; -byte T_INSW={ OW,0x66,0o155,_END}; -byte T_INSD={ O,0o155,_END}; -byte T_OUTSB={ O,0o156,_END}; -byte T_OUTSW={ OW,0x66,0o157,_END}; -byte T_OUTSD={ O,0o157,_END}; -byte T_MOVSB={ O,0o244,_END}; -byte T_MOVSW={ OW,0x66,0o245,_END}; -byte T_MOVSD={ O,0o245,_END}; -byte T_CMPSB={ O,0o246,_END}; -byte T_CMPSW={ OW,0x66,0o247,_END}; -byte T_CMPSD={ O,0o247,_END}; -byte T_STOSB={ O,0o252,_END}; -byte T_STOSW={ OW,0x66,0o253,_END}; -byte T_STOSD={ O,0o253,_END}; -byte T_LODSB={ O,0o254,_END}; -byte T_LODSW={ OW,0x66,0o255,_END}; -byte T_LODSD={ O,0o255,_END}; -byte T_SCASB={ O,0o256,_END}; -byte T_SCASW={ OW,0x66,0o257,_END}; -byte T_SCASD={ O,0o257,_END}; -byte T_REP={ O,0o362,_END}; -byte T_REPE={ O,0o363,_END}; -byte T_RAND={ O,0o146,_END}; //RAND: -byte T_ADDR={ O,0o147,_END}; //ADDR: -byte T_LEAVE={ O,0o311,_END}; -byte T_CLTS={ OW,0xF,6,_END}; -byte T_INVD={ OW,0xF,0o10,_END}; -byte T_WBINVD={ OW,0xF,0o11,_END}; -byte T_WRMSR={ OW,0xF,0x30,_END}; //WRMSR WRITE EDXEAX TO MODEL SPECIFIC REG #ECX -byte T_CPUID={ OW,0xF,0xA2,_END}; //CPUID IF EAX=1 SET EDXEAX TO CPU IDENTIFICATION VALUES -byte T_RDMSR={ OW,0xF,0x32,_END}; //RDMSR READ MODEL SPECIFIC REG #ECX TO EDXEAX -byte T_RDTSC={ OW,0xF,0x31,_END}; //RDTSC READ TIME STAMP COUNTER TO EDXEAX -byte T_RSM={ OW,0xF,0xAA,_END}; //RSM RESUME FROM SYSTEM MANAGEMENT MODE -//===== INTEL PENTIUM PRO INSTRUCTIONS -byte T_RDPMC={ OW,0xF,0x33,_END}; //READ PERFORMANCE MONITORING COUNTERS -byte T_UD2={ OW,0xF,0xB,_END}; //UNDEFINED INSTRUCTION EXCEPTION -byte T_EMMX={ OW,0xF,0x77,_END}; //EMPTY MMX STATE -byte T_SALC={ O,0xD6,_END}; -byte T_ICEBP={ O,0xF1,_END}; -byte T_PSHIMW={ OW,0xF,0x71,_END}; -byte T_PSHIMD={ OW,0xF,0x72,_END}; -byte T_PSHIMQ={ OW,0xF,0x73,_END}; - -byte T_NOT={ _B+OL1+SOE,O,0xF6,X2M,_END}; -byte T_NEG={ _B+OL1+SOE,O,0xF6,X3M,_END}; -byte T_INC={ _W+OL1+SOR,S,"10R", - _B+OL1+SOE,O,0xFE,X0M,_END}; -byte T_DEC={ _W+OL1+SOR,S,"11R", - _B+OL1+SOE,O,0xFE,X1M,_END}; -byte T_TEST={ _B+OL2+ERO,O,0o204,XRM,0, //ALPHA:WAS 204O - _B+OL2+REO,O,0o204,XRM,0, //" - _B+OL2+EAO,AR,CO,O,0o250,0, - _B+OL2+ECO,O,0xF6,X0M,_END}; -// EXTENDED 386 INTEGER MULTIPLICATION -byte T_IMUL={ _B+OL1+SOE,O,0xF6,X5M,0, //IMUL EB - _B+OL2+ECO,O,0xC0,X1M,0, - _B+OL2+EAO,-1,_1,O,0xD0,X1M,0, - _B+OL2+EAO,-1,rCL,O,0xD2,X1M,0, - _W+OL1+REO,OW,0xF,0o257,XRM,0, //IMUL RW, EW - OL3+REO+CC3,O,0o153,XRM,0, //IMUL RW, EW, DC - OL3+REO+CW3,O,0o151,XRM,_END}; //IMUL RW, EW, DW -byte T_SHLD={ OL3+ERO+CB3,OW,0xF,0o244,XRM,0, - OL3+ERO+CL3,OW,0xF,0o245,XRM,_END}; -byte T_SHRD={ OL3+ERO+CB3,OW,0xF,0o254,XRM,0, - OL3+ERO+CL3,OW,0xF,0o255,XRM,_END}; -byte T_MOVSX={ WB+OL2+REO,OW,0xF,0o276,XRM,0, - _DW+OL2+REO,OW,0xF,0o277,XRM,_END}; -byte T_MOVZX={ WB+OL2+REO,OW,0xF,0o266,XRM,0, - _DW+OL2+REO,OW,0xF,0o267,XRM,_END}; -byte T_BSWAP={ _D+OL1+SOR,OS,0xF,"31R",_END}; -byte T_BSF={ _W+OL2+REO,OW,0xF,0o274,XRM,_END}; -byte T_BSR={ _W+OL2+REO,OW,0xF,0o275,XRM,_END}; -byte T_CMPXCHG={_B+OL2+ERO,OW,0xF,0xB0,XRM,_END}; -byte T_CMPXCHG486={_B+OL2+ERO,OW,0xF,0xA7,XRM,_END}; -byte T_CMPXCHG8B={_B+OL2+ERO,OW,0xF,0xC7,XRM,_END}; -byte T_XADD={ _B+OL2+ERO,OW,0xF,0xC0,XRM,_END}; -byte T_XCHG={ _W+OL2+EAO,-1,AR,S,"22M", //ALPHA:WAS "22R" BUT GENERATED NOP - _W+OL2+EAO,AR,-1,S,"22R", - _B+OL2+REO,O,0o206,XRM,0, - _B+OL2+ERO,O,0o206,XRM,_END}; -byte T_MOV=0; //DUMMY BYTE -byte T_LEA={ _D+OL2+REO,O,0o215,XRM,_END}; //LEA RW, EN (X != 3) -byte T_LSS={ _D+OL2+REO,OW,0xF,0o262,XRM,_END};//LSS RW, EF (X != 3) -byte T_LFS={ _D+OL2+REO,OW,0xF,0o264,XRM,_END};//LFS RW, EF (X != 3) -byte T_LGS={ _D+OL2+REO,OW,0xF,0o265,XRM,_END};//LGS RW, EF (X != 3) -byte T_LES={ _D+OL2+REO,O,0o304,XRM,_END}; //LES RW, EF (X != 3) -byte T_LDS={ _D+OL2+REO,O,0o305,XRM,_END}; //LDS RW, EF (X != 3) -byte T_SET0={ NB+OL1+SOE,OW,0xF,0o220,X0M,_END}; -byte T_SET1={ NB+OL1+SOE,OW,0xF,0o221,X0M,_END}; -byte T_SET2={ NB+OL1+SOE,OW,0xF,0o222,X0M,_END}; -byte T_SET3={ NB+OL1+SOE,OW,0xF,0o223,X0M,_END}; -byte T_SET4={ NB+OL1+SOE,OW,0xF,0o224,X0M,_END}; -byte T_SET5={ NB+OL1+SOE,OW,0xF,0o225,X0M,_END}; -byte T_SET6={ NB+OL1+SOE,OW,0xF,0o226,X0M,_END}; -byte T_SET7={ NB+OL1+SOE,OW,0xF,0o227,X0M,_END}; -byte T_SET8={ NB+OL1+SOE,OW,0xF,0o230,X0M,_END}; -byte T_SET9={ NB+OL1+SOE,OW,0xF,0o231,X0M,_END}; -byte T_SETA={ NB+OL1+SOE,OW,0xF,0o232,X0M,_END}; -byte T_SETB={ NB+OL1+SOE,OW,0xF,0o233,X0M,_END}; -byte T_SETC={ NB+OL1+SOE,OW,0xF,0o234,X0M,_END}; -byte T_SETD={ NB+OL1+SOE,OW,0xF,0o235,X0M,_END}; -byte T_SETE={ NB+OL1+SOE,OW,0xF,0o236,X0M,_END}; -byte T_SETF={ NB+OL1+SOE,OW,0xF,0o237,X0M,_END}; -// -byte T_JCXZ={ OL1,_JB,O,0o343,_END}; -byte T_LOOPNZ={ OL1,_JB,O,0o340,_END}; -byte T_LOOPZ={ OL1,_JB,O,0o341,_END}; -byte T_LOOP={ OL1,_JB,O,0o342,_END}; -byte T_J0={ OL1,_JB,O,0o160,0, - OL1,_JW,6,OW,0o17,0o200,_END}; -byte T_J1={ OL1,_JB,O,0o161,0, - OL1,_JW,6,OW,0o17,0o201,_END}; -byte T_J2={ OL1,_JB,O,0o162,0, - OL1,_JW,6,OW,0o17,0o202,_END}; -byte T_J3={ OL1,_JB,O,0o163,0, - OL1,_JW,6,OW,0o17,0o203,_END}; -byte T_J4={ OL1,_JB,O,0o164,0, - OL1,_JW,6,OW,0o17,0o204,_END}; -byte T_J5={ OL1,_JB,O,0o165,0, - OL1,_JW,6,OW,0o17,0o205,_END}; -byte T_J6={ OL1,_JB,O,0o166,0, - OL1,_JW,6,OW,0o17,0o206,_END}; -byte T_J7={ OL1,_JB,O,0o167,0, - OL1,_JW,6,OW,0o17,0o207,_END}; -byte T_J8={ OL1,_JB,O,0o170,0, - OL1,_JW,6,OW,0o17,0o210,_END}; -byte T_J9={ OL1,_JB,O,0o171,0, - OL1,_JW,6,OW,0o17,0o211,_END}; -byte T_JA={ OL1,_JB,O,0o172,0, - OL1,_JW,6,OW,0o17,0o212,_END}; -byte T_JB={ OL1,_JB,O,0o173,0, - OL1,_JW,6,OW,0o17,0o213,_END}; -byte T_JC={ OL1,_JB,O,0o174,0, - OL1,_JW,6,OW,0o17,0o214,_END}; -byte T_JD={ OL1,_JB,O,0o175,0, - OL1,_JW,6,OW,0o17,0o215,_END}; -byte T_JE={ OL1,_JB,O,0o176,0, - OL1,_JW,6,OW,0o17,0o216,_END}; -byte T_JF={ OL1,_JB,O,0o177,0, - OL1,_JW,6,OW,0o17,0o217,_END}; -byte T_JMP={ OL1,_JB,O,0o353,0, //JMP SHORT CB - OL1,_JW,5,O,0o351,0, //JMP NEAR CW - _OW+OL1+SOE,O,0o377,X4M,0}; // JMP NEAR EN -byte T_JMPFAR={ _D+OL1+SOE,O,0o377,X5M,0, // JMP FAR EF - OL1+SOO_AF,O,0o352,_END}; //JMP FAR AF -byte T_JMPSHORT={ - OL1,_JB,O,0o353,_END}; //JMP SHORT CB -byte T_JMPNEAR={OL1,_JW,5,O,0o351,0, //JMP NEAR CW - _OW+OL1+SOE,O,0o377,X4M,_END}; // JMP NEAR EN -byte T_CALL={ OL1,_JW,5,O,0o350,0, //CALL CW - _OW+OL1+SOE,O,0o377,X2M,0}; //CALL EN -byte T_CALLFAR={ - OL1+SOO_AF,O,0o232,0, //CALL AF - _D+OL1+SOE,O,0o377,X3M,_END}; //CALL FAR EF -byte T_RETF={ 0,O,0o313,0, //RETF/RET FAR - _OW+OL1+SOC,O,0o312,_END}; //RETF DW/RET FAR DW -byte T_ENTER={ WB+OL2+EAO,CO,CO,O,0o310,_END}; -byte T_BOUND={ _W+OL2+REO,O,0o142,XRM,_END}; //BOUND RW, ED -/*byte T_INT={ NB+OL1+SO3,O,0o314,0, // !!! No interrupts in Win32 - NB+OL1+SOC,O,0o315,_END};*/ -byte T_IN={ NB+OL2+EAO,AR,CO,O,0o344,0, //IN AL, DB - WB+OL2+EAO,AR,CO,O,0o345,0, //IN AX,CO - _B+OL2+EAO,AR,rDX,O,0o354,0, //IN AL,DX - _OW+OL2+EAO,AR,rDX,O,0o355,_END}; //IN AX, DX -byte T_OUT={ NB+OL2+EAO,CO,AR,O,0o346,0, //OUT DB, AL - BW+OL2+EAO,CO,AR,O,0o347,0, //OUT DB, AX - WB+OL2+EAO,rDX,AR,O,0o356,0, //OUT DX, AL - _OW+OL2+EAO,rDX,AR,O,0o357,_END}; //OUT DX, AX -byte T_PUSH={ OL1+SOO_CC,O,0o152,0, - _D+OL1+SOR,S,"12R", - _D+OL1+SOE,O,0o377,X6M,0, - _D+OL1+SOC,O,0o150,0, - OL1+SOO_FS,OW,0xF,0o240,0, - OL1+SOO_GS,OW,0xF,0o250,0, - _OW+OL1+SOS,S,"0S6", //WIEDER ANS ENDE PACKEN - _END}; -byte T_RET={ _OW+OL1+SOC,O,0o302,0, //RET DW - O,0o303,0,_END}; //RET -byte T_POP={ _D+OL1+SOR,S,"13R", - _D+OL1+SOE,O,0o217,X0M,0, - OL1+SOO_FS,OW,0xF,0o241,0, - OL1+SOO_GS,OW,0xF,0o251,0, - _OW+OL1+SOS,S,"0S7",_END}; -byte T_ARPL={ _W+OL2+ERO,O,0o143,XRM,_END}; //ARPL ES, RW -byte T_SLDT={ _OW+OL1+SOE,OW,0xF,0,X0M,_END}; //SLDT EW -byte T_STR={ _OW+OL1+SOE,OW,0xF,0,X1M,_END}; //STR EW -byte T_LLDT={ _OW+OL1+SOE,OW,0xF,0,X2M,_END}; //LLDT EW -byte T_LTR={ _OW+OL1+SOE,OW,0xF,0,X3M,_END}; //LTR EW -byte T_VERR={ _OW+OL1+SOE,OW,0xF,0,X4M,_END}; //VERR EW -byte T_VERW={ _OW+OL1+SOE,OW,0xF,0,X5M,_END}; //VERW EW -byte T_LAR={ _OW+OL1+REO,OW,0xF,2,XRM,_END}; //LAR RW, EW -byte T_LSL={ _OW+OL1+REO,OW,0xF,3,XRM,_END}; //LSL RW, EW -byte T_SGDT={ _OW+OL1+SOM,OW,0xF,1,X0M,_END}; //SGDT EP -byte T_SIDT={ _OW+OL1+SOM,OW,0xF,1,X1M,_END}; //SIDT EP -byte T_LGDT={ _OW+OL1+SOM,OW,0xF,1,X2M,_END}; //LGDT EP -byte T_LIDT={ _OW+OL1+SOM,OW,0xF,1,X3M,_END}; //LIDT EP -byte T_SMSW={ _OW+OL1+SOE,OW,0xF,1,X4M,_END}; //SMSW EW -byte T_LMSW={ _OW+OL1+SOE,OW,0xF,1,X6M,_END}; //LMSW EW -//===== X486 INSTRUCTIONS -byte T_INVLPD={ _OW+OL1+SOM,OW,0xF,0o20,X7M,_END}; //INVLPG EA -//===== INTEL PENTIUM INSTRUCTIONS -byte T_CMPX8={ _OW+OL1+SOE,OW,0xF,0xC7,X1M,_END}; //CMPX8 EW 5 IF EDXEAX=MQ THEN MQ:=ECXEBX, ELSE EAXEDX:=MQ -byte T_CMOV={ _W+OL2,REO,OW,0xF,0x40,XRM,_END}; -//===== MMX INSTRUCTIONS -byte T_EMMS={ _END}; -byte T_UMOV={ _B+OL2,DER,OW,0xF,0x10,XRM,_END}; -#define _Q 1 -#define MMXE 1 -#define MMXP 1 -#define MMXPI 1 -#define MMXPE 1 -#define MMXEP 1 -byte T_PUNPCKLBW={ _D+OL2,MMXE,OW,0xF,0x60,_END}; -byte T_PUNPCKLWD={ _D+OL2,MMXE,OW,0xF,0x61,_END}; -byte T_PUNPCKLDQ={ _D+OL2,MMXE,OW,0xF,0x62,_END}; -byte T_PACKSSWB={ _Q+OL2,MMXE,OW,0xF,0x63,_END}; -byte T_PCMPGTB={ _Q+OL2,MMXE,OW,0xF,0x64,_END}; -byte T_PCMPGTW={ _Q+OL2,MMXE,OW,0xF,0x65,_END}; -byte T_PCMPGTD={ _Q+OL2,MMXE,OW,0xF,0x66,_END}; -byte T_PACKUSWB={ _Q+OL2,MMXE,OW,0xF,0x67,_END}; -byte T_PCMPEQB={ _Q+OL2,MMXE,OW,0xF,0x74,_END}; -byte T_PCMPEQW={ _Q+OL2,MMXE,OW,0xF,0x75,_END}; -byte T_PCMPEQD={ _Q+OL2,MMXE,OW,0xF,0x76,_END}; -byte T_PSRLW={ _Q+OL2,MMXE,OW,0xF,0xD1,_END}; -byte T_PSRLD={ _Q+OL2,MMXE,OW,0xF,0xD2,_END}; -byte T_PSRLQ={ _Q+OL2,MMXE,OW,0xF,0xD3,_END}; -byte T_PMULLW={ _Q+OL2,MMXE,OW,0xF,0xD5,_END}; -byte T_PSRAW={ _Q+OL2,MMXE,OW,0xF,0xE1,_END}; -byte T_PSRAD={ _Q+OL2,MMXE,OW,0xF,0xE2,_END}; -byte T_PMULHW={ _Q+OL2,MMXE,OW,0xF,0xE5,_END}; -byte T_PSLLW={ _Q+OL2,MMXE,OW,0xF,0xF1,_END}; -byte T_PSLLD={ _Q+OL2,MMXE,OW,0xF,0xF2,_END}; -byte T_PSLLQ={ _Q+OL2,MMXE,OW,0xF,0xF3,_END}; -byte T_PMADDWD={ _Q+OL2,MMXE,OW,0xF,0xF5,_END}; -byte T_PUNPCKHBW={ _Q+OL2,MMXE,OW,0xF,0x68,_END}; -byte T_PUNPCKHWD={ _Q+OL2,MMXE,OW,0xF,0x69,_END}; -byte T_PUNPCKHDQ={ _Q+OL2,MMXE,OW,0xF,0x6A,_END}; -byte T_PACKSSDW={ _Q+OL2,MMXE,OW,0xF, 0x6B,_END}; -byte T_MOVD={ _D+OL2,MMXPE,OW,0xF,0x6E,0, - _Q+OL2,MMXEP,OW,0xF,0x7E,_END}; -byte T_MOVQ={ _Q+OL2,MMXE,OW,0xF,0x6F,0, - _Q+OL2,MMXE,OW,0xF,0x7F,_END}; -byte T_PSUBUSB={ _Q+OL2,MMXE,OW,0xF,0xD8,_END}; -byte T_PSUBUSW={ _Q+OL2,MMXE,OW,0xF,0xD9,_END}; -byte T_PAND={ _Q+OL2,MMXE,OW,0xF,0xDB,_END}; -byte T_PADDUSB={ _Q+OL2,MMXE,OW,0xF,0xDC,_END}; -byte T_PADDUSW={ _Q+OL2,MMXE,OW,0xF,0xDD,_END}; -byte T_PANDN={ _Q+OL2,MMXE,OW,0xF,0xDF,_END}; -byte T_PSUBSB={ _Q+OL2,MMXE,OW,0xF,0xE8,_END}; -byte T_PSUBSW={ _D+OL2,MMXE,OW,0xF,0xE9,_END}; -byte T_POR={ _Q+OL2,MMXE,OW,0xF,0xEB,_END}; -byte T_PADDSB={ _Q+OL2,MMXE,OW,0xF,0xEC,_END}; -byte T_PADDSW={ _Q+OL2,MMXE,OW,0xF,0xED,_END}; -byte T_PXOR={ _Q+OL2,MMXE,OW,0xF,0xEF,_END}; -byte T_PSUBB={ _Q+OL2,MMXE,OW,0xF,0xF8,_END}; -byte T_PSUBW={ _Q+OL2,MMXE,OW,0xF,0xF9,_END}; -byte T_PSUBD={ _Q+OL2,MMXE,OW,0xF,0xFA,_END}; -byte T_PADDB={ _Q+OL2,MMXE,OW,0xF,0xFC,_END}; -byte T_PADDW={ _Q+OL2,MMXE,OW,0xF,0xFD,_END}; -byte T_PADDD={ _Q+OL2,MMXE,OW,0xF,0xFE,_END}; -byte T_PSRL={ _Q+OL2,MMXPI,OW,0xF,_END}; -byte T_PSRA={ _Q+OL2,MMXPI,OW,0xF,_END}; -byte T_PSLL={ _Q+OL2,MMXE,OW,0xF,_END}; - -byte Mnemonics={ -// FIRST OF ALL THE COMMANDS WITH A P-FLAG. THIS"LL MAKE THINGS EASIER FOR -// COMPARISON IN THE PARSE ENGINE - //P1=0-7 - "ADD","OR","ADC","SBB/BC","AND","SUB","XOR","CMP", - //P2=4-7 - "MUL","-","DIV","IDIV", - // IMUL ENTFERNT - //P3=0-5/7 - "ROL","ROR","RCL","RCR","SHL/AL","SHR","-","SAR", - //P4=4-7 - "BT","BTS","BTR","BTC", - // USUAL COMMANDS - "NOT","NEG","INC","DEC","TEST", "IMUL","SHLD","SHRD", - "DAA","DAS","AAA","AAS","AAM","AAD", - "MOVSX","MOVZX","CBW","CWDE","CWD","CDQ", - "BSWAP","XLAT/LATB","BSF","BSR", - "CMPXCHG","CMPXCHG486","CMPXCHG8B","XADD", - "NOP","WAIT","LOCK","HLT", //"INT", - "INTO","IRET", - "POPF","POPFD","PUSHF","PUSHFD","SAHF","LAHF", - "CMC","CLC","STC","CLI","STI","CLD","STD", - "PUSH","PUSHA","PUSHAD","POP","POPA","POPAD", - "XCHG","MOV","LEA","LSS","LFS","LGS","LES","LDS", - "ADDR","RAND", - "IN","OUT","INSB","INSW","INSD","OUTSB","OUTSW","OUTSD", - "MOVSB","MOVSW","MOVSD","CMPSB","CMPSW","CMPSD", - "STOSB","STOSW","STOSD","LODSB","LODSW","LODSD", - "SCASB","SCASW","SCASD","REP/EPNE/EPNZ","REPE/EPZ", - "JCXZ/ECXZ","LOOP","LOOPZ/OOPE","LOOPNZ/OOPNE", - "JO","JNO","JC/B/NAE","JNC/AE/NB", - "JE/Z","JNE/NZ","JBE/NA","JA/NBE", - "JS","JNS","JP/PE","JNP/PO","JL/NGE","JGE/NL", - "JLE/NG","JG/NLE", - "SETO","SETNO","SETC/ETB/ETNAE","SETNC/ETAE/ETNB", - "SETE/ETZ","SETNE/ETNZ","SETBE/ETNA","SETA/ETNBE", - "SETS","SETNS","SETP/ETPE","SETNP/ETPO","SETL/ETNGE","SETGE/ETNL", - "SETLE/ETNG","SETG/ETNLE", - "JMPS","JMPN","JMPF","JMP", - "CALL","CALLF","RET","RETF", - "ENTER","LEAVE","BOUND","ARPL", - "SLDT","STR","LLDT","LTR","VERR","VERW","LAR","LSL", - "SGDT","SIDT","LGDT","LIDT","SMSW","LMSW","CLTS", - "INVD","WBINVD","INVLPD", - //INTEL PENTIUM COMMANDS - "WRMSR","CMPX8/MPXCHG8B","CPUID","RDMSR","RDTSC","RSM", - //INTEL PENTIUM PRO INSTRUCTIONS - "RDPMC","UD2","EMMX","SETALC", - //MMX INSTRUCTIONS - "MOVD","MOVQ", //MOVE MMX REG - "PACKUS/PACKUSWB", //PACK MMX REG WITH UNSIGNED SATURATION - "PACKSSWB","PACKSSDW", //PACK MMX REG WITH SIGNED SATURATION - "PUNPCKHBW","PUNPCKHWD", - "PUNPCKHDQ", //UNPACK HIGH ORDER - "PUNPCKLBW","PUNPCKLWD", - "PUNPCKLDQ", //UNPACK LOW ORDER - "PADDB","PADDW","PADDD", //ADD MMX REG WITH WRAP-AROUND - "PADDSB","PADDSW", //" WITH SIGNED SATURATION - "PADDUSB","PADDUSW", //" WITH UNSIGNED SATURATION - "PSUBB","PSUBW","PSUBD", //SUBTRACT MMX REG - "PSUBSB","PSUBSW","PSUBUSB","PSUBUSW", - "PMULH/PMULHW","PMULL/PMULLW","PMADD/PMADDWD", - "PSLLW","PSLLD","PSLLQ","PSRLW","PSRLD","PSRLQ", - "PSRAW","PSRAD","PCMPEQB","PCMPEQW","PCMPEQD", - "PCMPGTB","PCMPGTW","PCMPGTD","PAND","PANDN","POR","PXOR","EMMS",_END}; - -dword TAB_MNEMONICS={ - #T_NOT,#T_NEG,#T_INC,#T_DEC,#T_TEST, - #T_IMUL,#T_SHLD,#T_SHRD, - #T_DAA,#T_DAS,#T_AAA,#T_AAS,#T_AAM,#T_AAD, - #T_MOVSX,#T_MOVZX,#T_CBW,#T_CWDE,#T_CWD,#T_CDQ, - #T_BSWAP,#T_XLATB, - #T_BSF,#T_BSR,#T_CMPXCHG,#T_CMPXCHG486,#T_CMPXCHG8B,#T_XADD, - #T_NOP,#T_WAIT,#T_LOCK,#T_HLT, -// #T_INT, - #T_INTO,#T_IRET, - #T_POPF,#T_POPFD,#T_PUSHF,#T_PUSHFD, - #T_SAHF,#T_LAHF, - #T_CMC,#T_CLC,#T_STC,#T_CLI,#T_STI,#T_CLD,#T_STD, - #T_PUSH,#T_PUSHA,#T_PUSHAD, - #T_POP,#T_POPA,#T_POPAD, - #T_XCHG,#T_MOV, - #T_LEA,#T_LSS,#T_LFS,#T_LGS,#T_LES,#T_LDS, - #T_ADDR,#T_RAND, - #T_IN,#T_OUT, - #T_INSB,#T_INSW,#T_INSD, - #T_OUTSB,#T_OUTSW,#T_OUTSD, - #T_MOVSB,#T_MOVSW,#T_MOVSD, - #T_CMPSB,#T_CMPSW,#T_CMPSD, - #T_STOSB,#T_STOSW,#T_STOSD, - #T_LODSB,#T_LODSW,#T_LODSD, - #T_SCASB,#T_SCASW,#T_SCASD, - #T_REP, - #T_REPE, - #T_JCXZ,#T_LOOP,#T_LOOPZ,#T_LOOPNZ, - #T_J0,#T_J1,#T_J2,#T_J3, - #T_J4,#T_J5,#T_J6,#T_J7, - #T_J8,#T_J9,#T_JA,#T_JB, - #T_JC,#T_JD,#T_JE,#T_JF, - #T_SET0,#T_SET1,#T_SET2,#T_SET3, - #T_SET4,#T_SET5,#T_SET6,#T_SET7, - #T_SET8,#T_SET9,#T_SETA,#T_SETB, - #T_SETC,#T_SETD,#T_SETE,#T_SETF, - #T_JMPSHORT,#T_JMPNEAR,#T_JMPFAR,#T_JMP, - #T_CALL,#T_CALLFAR, - #T_RET,#T_RETF, - #T_ENTER,#T_LEAVE, - #T_BOUND,#T_ARPL, - #T_SLDT,#T_STR,#T_LLDT,#T_LTR,#T_VERR,#T_VERW, - #T_LAR,#T_LSL, - #T_SGDT,#T_SIDT,#T_LGDT,#T_LIDT, - #T_SMSW,#T_LMSW,#T_CLTS, - #T_INVD,#T_WBINVD,#T_INVLPD, -//INTEL PENTIUM INSTRUCTIONS - #T_WRMSR,#T_CMPX8,#T_CPUID,#T_RDMSR,#T_RDTSC,#T_RSM, -//INTEL PENTIUM PRO INSTRUCTIONS - #T_RDPMC,#T_UD2,#T_EMMX,#T_SALC, -//MMX INSTRUCTIONS - #T_MOVD,#T_MOVQ, //MOVE MMX REG - #T_PACKUSWB, //PACK MMX REG WITH UNSIGNED SATURATION - #T_PACKSSWB,#T_PACKSSDW, //PACK MMX REG WITH SIGNED SATURATION - #T_PUNPCKHBW,#T_PUNPCKHWD,#T_PUNPCKHDQ, //UNPACK HIGH ORDER - #T_PUNPCKLBW,#T_PUNPCKLWD,#T_PUNPCKLDQ, //UNPACK LOW ORDER - #T_PADDB,#T_PADDW,#T_PADDD, //ADD MMX REG WITH WRAP-AROUND - #T_PADDSB,#T_PADDSW, //" WITH SIGNED SATURATION - #T_PADDUSB,#T_PADDUSW, //" WITH UNSIGNED SATURATION - #T_PSUBB,#T_PSUBW,#T_PSUBD, //SUBTRACT MMX REG - #T_PSUBSB,#T_PSUBSW, - #T_PSUBUSB,#T_PSUBUSW, - #T_PMULHW, - #T_PMULLW, - #T_PMADDWD, - #T_PSLLW,#T_PSLLD,#T_PSLLQ, - #T_PSRLW,#T_PSRLD,#T_PSRLQ, - #T_PSRAW,#T_PSRAD, - #T_PCMPEQB,#T_PCMPEQW,#T_PCMPEQD, - #T_PCMPGTB,#T_PCMPGTW,#T_PCMPGTD, - #T_PAND, - #T_PANDN, - #T_POR, - #T_PXOR, - #T_EMMS}; - - diff --git a/programs/develop/c--/trunk/parser.h-- b/programs/develop/c--/trunk/parser.h-- deleted file mode 100644 index 503185f7b2..0000000000 --- a/programs/develop/c--/trunk/parser.h-- +++ /dev/null @@ -1,630 +0,0 @@ -// ---- Генерация выражения -DoExpr(dword var,vtok,vtype,mnem) -byte varName[2*IDLENGTH]; -{ - IF(tok2notstopper()){ - IF(vtok==tk_var)Expression("eax",tk_reg,tk_dword); - ELSE{ - Expression(var,vtok,vtype); - return; - } - } - else{ // Один операнд - tok=GetVarname(#varName); - IF(tok==tk_reg)wsprintfA(#mapstr,"%s %s,%s",mnem,var,#varName); - else IF(tok==tk_var){ - IF(vtok==tk_var)Expression("eax",tk_reg,tk_dword); - ELSE wsprintfA(#mapstr,"%s %s,%s",mnem,var,#varName); - } - else IF(tok==tk_number)wsprintfA(#mapstr,"%s %s,%d",mnem,var,DoConstMath()); - ELSE IF(tok==tk_postnumber)wsprintfA(#mapstr,"%s %s#%s",mnem,var,#varName); - ELSE IF(tok==tk_locnumber){ - wsprintfA(#mapstr,"lea ebx,%s",#varName); - wsprintfA(#mapstr,"%s %s,ebx",mnem,var); - return; - } - Asm(#mapstr); - RETURN; - } - IF(vtype==tk_byte)||(vtype==tk_char)wsprintfA(#mapstr,"%s %s,al",mnem,var); - ELSE IF(vtype==tk_word)||(vtype==tk_short)wsprintfA(#mapstr,"%s %s,ax",mnem,var); - ELSE IF(vtype==tk_dword)||(vtype==tk_int)wsprintfA(#mapstr,"%s %s,eax",mnem,var); - Asm(#mapstr); -} - -// ---- Разборка и трансляция выражений -dword Expression(dword dest,dtok,dtype) -byte s[IDLENGTH]; -{ - GetInto(dest,dtok,dtype); - for(;;){ - Term(#s,dtype); - IF(tok==tk_plus){ - Term(#s,dtype); - wsprintfA(#mapstr,"add %s,%s",dest,#s); - Asm(#mapstr); - } - else IF(tok==tk_minus){ - Term(#s,dtype); - wsprintfA(#mapstr,"sub %s,%s",dest,#s); - Asm(#mapstr); - } - else IF(tok==tk_or){ - Term(#s,dtype); - wsprintfA(#mapstr,"or %s,%s",dest,#s); - Asm(#mapstr); - } - else IF(tok==tk_xor){ - Term(#s,dtype); - wsprintfA(#mapstr,"xor %s,%s",dest,#s); - Asm(#mapstr); - } - else IF(tok==tk_assign)||(tok==tk_equalto){ - Term(#s,dtype); - wsprintfA(#mapstr,"cmp %s,%s",dest,#s); - Asm(#mapstr); - Asm("sete al"); -SE: - wsprintfA(#mapstr,"movzx %s,al",dest); - Asm(#mapstr); - } - else IF(tok==tk_notequal){ - Term(#s,dtype); - wsprintfA(#mapstr,"cmp %s,%s",dest,#s); - Asm(#mapstr); - Asm("setne al"); - GOTO SE; - } - else IF(tok==tk_greater){ - Term(#s,dtype); - wsprintfA(#mapstr,"cmp %s,%s",dest,#s); - Asm(#mapstr); - Asm("setg al"); - $JMP SE; - } - else IF(tok==tk_greaterequal){ - Term(#s,dtype); - wsprintfA(#mapstr,"cmp %s,%s",dest,#s); - Asm(#mapstr); - Asm("setge al"); - $JMP SE; - } - else IF(tok==tk_less){ - Term(#s,dtype); - wsprintfA(#mapstr,"cmp %s,%s",dest,#s); - Asm(#mapstr); - Asm("setl al"); - $JMP SE; - } - ELSE IF(tok==tk_lessequal){ - Term(#s,dtype); - wsprintfA(#mapstr,"cmp %s,%s",dest,#s); - Asm(#mapstr); - Asm("setle al"); - $JMP SE; - } - ELSE BREAK; - } - return(relation); -} - -// ---- Чтение очередного элемента выражения -Factor(dword f,ftype) -{ - NextTok(); - IF(tok==tk_openbracket){ - NextTok(); - PushEAX(); - Expression("eax",tk_reg,ftype); - Asm("pop ebx; xchg eax,ebx"); - wsprintfA(f,"%s","ebx"); - } - else IF(tok==tk_number)wsprintfA(f,"%#x",DoConstMath()); - else IF(tok==tk_postnumber)wsprintfA(f,"#%s",#string); - else IF(tok==tk_proc){ - PushEAX(); - DoAnyProc(); - Asm("pop ebx; xchg eax,ebx"); - wsprintfA(f,"%s","ebx"); - } - ELSE IF(tok==tk_API){ - PushEAX(); - doAPI(); - Asm("pop ebx; xchg eax,ebx"); - wsprintfA(f,"%s","ebx"); - } - ELSE IF(tok==tk_var)||(tok==tk_param)||(tok==tk_local)||(tok==tk_openblock)|| - (tok==tk_reg)GetVarname(f); -} - -// ---- -GetInto(dword dest,dtok,dtype) -dword tk; -{ - tk=0; -DOCASE: - IF(tok==tk_minus){ -F_0: - tk=tok; - NextTok(); - GOTO DOCASE; - } - else IF(tok==tk_not){ - relation^=1; - GOTO F_0; - } - else IF(tok==tk_openbracket){ - NextTok(); - Expression(dest,dtok,dtype); - } - else IF(tok==tk_number){ - IF(tk)wsprintfA(#mapstr,"mov %s,-%#x",dest,DoConstMath()); - ELSE wsprintfA(#mapstr,"mov %s,%#x",dest,DoConstMath()); - Asm(#mapstr); - tk=0; - } - else IF(tok==tk_postnumber){ - wsprintfA(#mapstr,"mov %s,#%s",dest,#string); - Asm(#mapstr); - } - else IF(tok==tk_locnumber){ - wsprintfA(#mapstr,"lea ebx,%s",#string); - Asm(#mapstr); - wsprintfA(#mapstr,"mov %s,ebx",dest); - Asm(#mapstr); - } - ELSE IF(tok==tk_proc)DoAnyProc(); - ELSE IF(tok==tk_API)doAPI(); - ELSE IF(tok==tk_var)||(tok==tk_local)||(tok==tk_param)||(tok==tk_reg)|| - (tok==tk_openblock)GetIntoVar(dest,dtok,dtype); - ELSE preerror("Wrong expression member"); -// wsprintfA(#string,dest,"mov %s,%s",#mapstr); -// ESP+=16; Asm(#mapstr); - IF(tk==tk_minus){ - wsprintfA(#mapstr,"neg %s",dest); - Asm(#mapstr); - } - IF(tk==tk_not){ - wsprintfA(#mapstr,"not %s",dest); - Asm(#mapstr); - } -} - -// ---- -GetIntoVar(dword dName,dTok,dType) -byte varName[2*IDLENGTH]; -dword vtype,vtok; -{ - if(dTok==tk_reg){ - if(tok==tk_reg){ // Reg = Reg - IF(dType==tk_dword){// Reg32=Reg - IF(type==tk_dword){ - wsprintfA(#mapstr,"mov %s,%s",dName,#string); - Asm(#mapstr); - } - ELSE IF(type==tk_word)||(type==tk_byte){ -RDW: - wsprintfA(#mapstr,"movzx %s,%s",dName,#string); - Asm(#mapstr); - } - } - else IF(dType==tk_word){ // Reg=Reg - IF(type==tk_dword){ -GERR: - warning("Not same size\n"); - } - ELSE IF(type==tk_word){ - wsprintfA(#mapstr,"mov %s,%s",dName,#string); - Asm(#mapstr); - } - ELSE IF(type==tk_byte)GOTO RDW; - } - ELSE IF(dType==tk_byte){ // Reg=Reg - IF(type==tk_dword)||(type==tk_word)GOTO GERR; - IF(type==tk_byte){ - wsprintfA(#mapstr,"mov %s,%s",dName,#string); - Asm(#mapstr); - } - } - } - else if(tok==tk_var)||(tok==tk_param)||(tok==tk_local)||(tok==tk_openblock){ // Reg = Var - vtype=type; vtok=GetVarname(#varName); - IF(vtype==tk_dword)||(vtype==tk_int)||(dType==vtype){ - wsprintfA(#mapstr,"mov %s,%s",dName,#varName); - } - ELSE IF(vtype==tk_word)||(vtype==tk_byte){ - wsprintfA(#mapstr,"movzx %s,%s",dName,#varName); - } - ELSE IF(vtype==tk_short)||(vtype==tk_char){ - wsprintfA(#mapstr,"movsx %s,%s",dName,#varName); - } - Asm(#mapstr); - } - else IF(tok==tk_number){ // Reg = Const - wsprintfA(#mapstr,"mov %s,%d",dName,DoConstMath()); - Asm(#mapstr); - } - else IF(tok==tk_postnumber){ // Reg = #Var - GetVarname(#varName); - wsprintfA(#mapstr,"mov %s,#%s",dName,#varName); - Asm(#mapstr); - } - ELSE IF(tok==tk_locnumber){ // Reg = #locVar - vtype=type; vtok=GetVarname(#varName); - wsprintfA(#mapstr,"lea %s,%s",dName,#varName); - Asm(#mapstr); - } - } - else if(dTok==tk_var){ - if(tok==tk_reg){ // Var = Reg; - IF(type==tk_dword){ - wsprintfA(#mapstr,"mov dword %s,%s",dName,#string); - Asm(#mapstr); - } - ELSE IF(type==tk_word){ - wsprintfA(#mapstr,"mov word %s,%s",dName,#string); - Asm(#mapstr); - } - ELSE IF(type==tk_byte){ - wsprintfA(#mapstr,"mov byte %s,%s",dName,#string); - Asm(#mapstr); - } - } - else if(tok==tk_var){ // Var = Var; - vtype=type; - vtok=GetVarname(#varName); - IF(dType==tk_byte)||(dType==tk_char){ - wsprintfA(#mapstr,"mov al,%s",#varName); - Asm(#mapstr); - wsprintfA(#mapstr,"mov %s,al",dName); - Asm(#mapstr); - } - else if(dType==tk_word)||(dType==tk_short){ - IF(vtype==tk_byte){ - wsprintfA(#mapstr,"movzx ax,%s",#varName); - Asm(#mapstr); - } - else IF(vtype==tk_char){ - wsprintfA(#mapstr,"movsx ax,%s",#varName); - Asm(#mapstr); - } - ELSE IF(vtype==tk_word)||(vtype==tk_short){ - wsprintfA(#mapstr,"mov ax,%s",#varName); - Asm(#mapstr); - } - ELSE IF(vtype==tk_dword)||(vtype==tk_int){ - wsprintfA(#mapstr,"mov ax,word %s",#varName); - Asm(#mapstr); - } - wsprintfA(#mapstr,"mov %s,ax",dName); - Asm(#mapstr); - } - else if(dType==tk_dword)||(dType==tk_int){ - IF(vtype==tk_byte)||(vtype==tk_word){ - wsprintfA(#mapstr,"movzx eax,%s",#varName); - Asm(#mapstr); - } - ELSE IF(vtype==tk_char)||(vtype==tk_short){ - wsprintfA(#mapstr,"movsx eax,%s",#varName); - Asm(#mapstr); - } - ELSE IF(vtype==tk_dword)||(vtype==tk_int){ - wsprintfA(#mapstr,"mov eax,%s",#varName); - Asm(#mapstr); - } - wsprintfA(#mapstr,"mov %s,eax",dName); - Asm(#mapstr); - } - } - else IF(tok==tk_number){ // Var = Const; - wsprintfA(#mapstr,"mov %s,%d",dName,DoConstMath()); - Asm(#mapstr); - } - else IF(tok==tk_postnumber){ // Var = #Var; - vtype=type; vtok=GetVarname(#varName); - wsprintfA(#mapstr,"mov %s,#%s",dName,#varName); - Asm(#mapstr); - } - ELSE IF(tok==tk_locnumber){ // Var = #locVar; - vtype=type; vtok=GetVarname(#varName); - wsprintfA(#mapstr,"lea ebx,%s",#varName); - Asm(#mapstr); - wsprintfA(#mapstr,"mov %s,ebx",dName); - Asm(#mapstr); - } - } -} - -// ---- Чтение переменной: VarName[reg+reg*Scale+disp] -dword GetVarname(dword varName) -dword vtok; -{ - IF(tok==tk_openblock)GOTO G0; - lstrcpyA(varName,#string); - vtok=tok; - IF(vtok==tk_local)vtok=tk_var; - ELSE IF(vtok==tk_param)vtok=tk_var; - if(tok2==tk_openblock){ - NextTok(); -G0: - vtok=tk_var; - lstrcatA(varName,"["); - for(;;){ - NextTok(); - IF(tok==tk_reg)lstrcatA(varName,#string); - else IF(tok==tk_plus)lstrcatA(varName,"+"); - else IF(tok==tk_mult)lstrcatA(varName,"*"); - ELSE IF(tok==tk_number){ - wsprintfA(#mapstr,"%d",DoConstMath()); - lstrcatA(varName,#mapstr); - } - ELSE IF(tok==tk_postnumber){ - lstrcatA(varName,"#"); - lstrcatA(varName,#string); - } - ELSE IF(tok==tk_closeblock){ - lstrcatA(varName,"]"); - BREAK; - } - ELSE preerror("Illegal index expression in []"); - } - } - return(vtok); -} - -// ---- -Term(dword t,ttype) -{ - for(;;){ - Factor(t,ttype); - IF(tok==tk_mult){ - Factor(t,ttype); - IF(tok==tk_number){ - wsprintfA(#mapstr,"mov ebx,%d",DoConstMath()); - Asm(#mapstr); - wsprintfA(#mapstr,"mul %s","ebx"); - } - ELSE wsprintfA(#mapstr,"mul %s",t); - Asm(#mapstr); - } - else IF(tok==tk_div){ - Factor(t,ttype); - IF(tok==tk_number){ - wsprintfA(#mapstr,"mov ebx,%d",DoConstMath()); - Asm(#mapstr); - wsprintfA(#mapstr,"div %s","ebx"); - } - ELSE wsprintfA(#mapstr,"div %s",t); - Asm(#mapstr); - } - else IF(tok==tk_mod){ - Factor(t,ttype); - IF(tok==tk_number){ - wsprintfA(#mapstr,"mov ebx,%d",DoConstMath()); - Asm(#mapstr); - wsprintfA(#mapstr,"div %s","ebx"); - } - ELSE wsprintfA(#mapstr,"div %s",t); - Asm(#mapstr); - Asm("xchg eax,edx"); - } - ELSE IF(tok==tk_and){ - Factor(t,ttype); - IF(tok==tk_number)wsprintfA(#mapstr,"and ebx,%d",DoConstMath()); - ELSE wsprintfA(#mapstr,"and eax,%s",t); - Asm(#mapstr); - } - ELSE IF(tok==tk_not)Asm("not eax"); - ELSE BREAK; - } -} - -// ---- Сохранение EAX в стеке -PushEAX() -{ - Asm("push eax"); -} - -// ---- Сохранение EAX в стеке -/*PopEAX() -{ - Asm("pop eax"); -} */ - -// ---- Обработка строки-параметра: proc("string") -dword AddPoststring() -dword returnvalue; -{ - IF(posts >= MAXPOSTS){ - preerror("cannot add post string, post queue full"); - ExitProcess(-1); - } - EBX=posts<<2+posttype; - DSDWORD[EBX] = POST_STR; - EBX=posts<<2+postloc; - DSDWORD[EBX] = outptr; - posts++; - returnvalue = MAXDATA-1-poststrptr; - ESI=#string; - EBX> exe-file. Кроме того, большой набор -различных библиотек... которые к тому же существенно меняются от -версии к версии, что совсем не радует. И если вы переходите на новую, -более продвинутую версию компилятора, то нет никакой гарантии, что -вы сможете на нем перекомпилировать свои старые программы - примером -служит DDK от MicroSoft. - Sphinx C-- изначально был задуман и реализован для создания -компактных по размеру COM-файлов и поэтому вполне подходит для -генерации 32-разрядных приложения в модели плоской (flat) памяти. -Помимо этого большим плюсом является идея открытого кода для всех -вызываемых в программе библиотечных функций, реализованная посредством -*.h-- файлов. - Еще одна идея из компилятора Sphinx C--, заслуживающая внимания, - это -динамические процедуры, т.е. процедуры, которые могут быть помещены в тело -компилируемой программы только тогда, когда к ним есть обращение. Таким -образом, в процессе написания программы с использованием динамических -процедур гарантируется включение в тело программы только того кода, -который действительно необходим. - В процессе работы по переводу компилятора Sphinx C-- на платформу Win32 -произведены весьма существенные изменения как в самом компиляторе, так и в -идеях, на которых он реализован. Я не буду здесь выделять все отличия -настоящего компилятора от его прародителя по той простой причине, что те, кто -с ним знаком, их смогут увидеть сами, а тем, кто не имел дела с С--, нет нужды -вникать в эти детали. - Отмечу, однако, что принцип генерации кода, использовавшийся в С--, заменен -на принцип, используемый в макроассемблере TMA Свена Клозе (TMA macro assembler -Sven Klose), с проведением его адаптации к нуждам С--. - В результате появился данный компилятор, целью которого является заполнение -ниши между языком ассемблера и языком С. - - Описание языка. - - Идентификаторы. - - Идентификаторы должны начинаться с буквы или знака подчеркивания, если -являются глобальными, или же должны начинаться с символа @, если они локальные. -Далее может идти любая комбинация цифр, букв или знаков подчеркивания длиной -не более 63 символов. Буквы могут быть как из латинского, так и из национального -алфавита. Несколько примеров: - GoHome - _1234 - ПримерИдентификатора - @LocalLabel2 - - Все идентификаторы, кроме зарезервированных, являются чувствительными к -регистру, т.е. идентификаторы: ToDo и Todo компилятор воспримет как разные. - - Зарезервированные идентификаторы - - Ниже приводится список зарезервированных идентификаторов языка, которые -не могут быть использованы при создании программы иначе, как это определено -в языке: - byte char word short dword int - if else cycle do while return - docase case continue break extract from - enum struct - carryflag overflow zeroflag - notcarryflag notoverflow notzeroflag - а также названия регистров и мнемоники команд ассемблера. - - Еще раз подчеркну, что зарезервироанные слова не зависят от регистра, т.е. -Enum и eNuM компилятор воспримет в любом из вариантов, как начало списка -нумерованных констант. - - Константы - - Числовые константы могут быть заданы в одной из четырех систем счисления: -десятичной, шестнадцатиричной, восмеричной или двоичной. - Десятичные числовые константы задаются обычным образом: 444 или 007. - Шестнадцатиричное представление констант начинается с комбинации 0x: 0xFFF -или 0x088. - Восмеричное представление констант начинается с комбинации 0o: 0o777 или -0o10. - Двоичное представление констант начинается с комбинации 0b: 0b111101 или -0b11101010. - - Символы в константах заключаются в одиночные кавычки ('). Так же как и в С -символы могут заданы с помощью указания их кода после символа '\'. Список -спецсимволов: - '\a', '\b', '\f', '\l', '\n', '\r', '\t' - для форматирования вывода - '\x??' или '\???' - ASCII-символ. Код символа задан либо в 16, 10 значением. - Любые символы после '\' просто принимаются компилятором, таким образом -одиночную кавычку можно указать как '\''. - - Строковые константы задаются путем заключения их в двойные кавычки ("). -Внутри строковой константы допускается указание спецсимволов в одиночных -кавычках. Примеры строковых констант: - "Пример строковой константы\n" - "Need '\"'word'\"' in data declaration" -> Need "word" in data declaration - - При определении числовых и символьных констант допускается использование -выражений, которые вычисляются в процессе компиляции. Значением константы -будет результат вычисления выражения: - 1*2*3/2+4 даст значение константы 7. - Вычисления проводятся слева-направо без учета приоритета операций. - - Стандартные типы данных - - Имеется шесть стандартных типов данных: byte, char, word, short, dword -и int. В таблице приведены размер и диапазон значений для каждого типа: - ------------------------------------------------------------------- - Тип | Размер | Диапазон значений - переменной | в байтах | (десятичн.) | (hex) - ------------------------------------------------------------------- - byte | 1 | 0...255 | 0...0xFF - char | 1 | -127...127 | 0x80...0x7F - word | 2 | 0...65535 | 0...0xFFFF - short | 2 | -32768...32767 | 0x8000...0x7FFF - dword | 4 | 0...4294967295 | 0...0xFFFFFFFF - int | 4 | -2147483648... | 0x80000000 ... - | | 2147483647 | 0x7FFFFFFF - ------------------------------------------------------------------- - - Глобальные переменные - - Объявление переменных имеет обычный для С синтаксис: - - <тип> <список идентификаторов>; - - Список идентификаторов состоит из одного или более идентификаторов, -разделенных запятыми. В списке также могут присутсвовать одномерные массивы, -объявляемые в виде: - <идентификатор>[<размерность>]. - - Примеры объявлений переменных: - dword i,j; // i и j типа dword - byte Tab='\t'; // переменная Tab типа byte с начальным значением - char string[]="This is a string\n"; - int z,b[6]; // z типа int и массив целых - b - - Выражения - - Выражения состоят из левой и правой частей, разделенных либо операцией -присваивания, либо операцией сравнения. Левая часть выражения может быть -либо переменной, либо регистром. В правой части выражения может находиться -произвольное количество переменных, функций, констант, скобок и знаков операций. -Ниже приводится таблица всех допустимых операций: -------------------------------------------------------------------------- -Операция | Значение | Пример -------------------------------------------------------------------------- - = | присвоить или | edi = 33; - | проверить равенство | while(ch = 'a') - + | сложить | eax = Count + 5; - - | вычесть | Count = eax - edi; - * | умножить | x = y * 3; - / | разделить | y = ecx / x; - % | остаток деления | y = edi / 7; - & | логическое AND | a = B & c; - | | логическое OR | a = B | c; - ^ | логическое XOR | a = B ^ c; - << | сдвиг бит влево | x = y << 5; - >> | сдвиг бит вправо | x = y >> 6; - += | увеличить на | a += 6; // a = a + 6; - -= | уменьшить на | a -= 5; // a = a - 5; - &= | побитный AND | a &= 0xF; // a = a & 0xF; - |= | побитный OR | a |= 0o77; // a = a | 0o77; - ^= | побитный XOR | a ^= 0b1101; // a = a ^ 0b1101; - <<= | сдвиг бит влево | a <<= 7; // a = a << 7; - >>= | сдвиг бит вправо | a >>= 3; // a = a >> 3; - >< | обмен(swap) | x >< y; // temp=y; y=x; x=temp; - == | проверить равенство | if( x=='7' ) // для тех, кому так привычнее - > | больше чем | case( x > y ) - < | меньше чем | if( a < 0 ) - >= | больше или равно | while(( b >= a ) & ( x >= ( y - 7 ))) - <= | меньше или равно | if( y <= ( a + b - 30 )) -!= или <>| не равно | case( a != b) или же case( a <> b) - # | адрес переменной | esi = #Count; // esi=адрес переменной Count - - Функции - - Объявление функций имеет вид: - - <тип> <идентификатор>(<список параметров>) - -Список параметров задает типы и имена формальных параметров, используемых при -вызове функции. Компилятор не осуществляет проверку соответствия списка -формальных параметров функции фактическим, поэтому следует внимательно следить -за корректностью вызова функций. - Тип возвращаемого из функции значения можно не указывать. В этом случае -по умолчанию считается, что функция возвращает значение типа dword. Значение -помещается при возврате из функции в регистр eax для типов dword и int, в -регистр ax для типов word и short и в регистр al для типов byte и char. - В списке параметров для каждого параметра указывается его тип. Параметры -одного типа, идущие подряд, разделяются запятыми. Формальные параметры разного -типа в объявлении функции разделяются символом ;. Если тип параметра не задан, -то считается, что параметр имеет тип dword. Не зависимо от типа параметра при -вызове функции для каждого параметра выделяется 4 байта (dword). Это связано -с тем, что в Win32 стек всегда должен иметь выравнивание (alignment) на границу -двойного слова. - Примеры объявления функций и их вызовов. - Объявление Пример вызова - char ToUpper(char ch) upChar = ToUpper('i'); - MergeStrings(dword dest,str1,str2) MergeStrings(#str,"One","+Two"); - получим str="One+Two" - Convert(dword str; int number,base) Convert(#num, -567, 16); - - При вызове функции первый параметр помещается в стек последним. Пример: - WriteFile(handle,"Hello World!\n",14,#dWriteFileCount,0); -будет реализован: - push 0 - push #dWriteFileCount - push 14 - push #"Hello World!" - push handle - call WriteFile - При возврате из функции стек очищается от параметров командой: ret number. - - Все объявляемые в программе функции являются динамическими. Это значит, -что код функции вставляется в программу лишь только в случае обращения к ней. -То же самое относится и к любым глобальным переменным в программе. - - Структурные операторы - - Применение структурных операторов в программе делает ее более удобной для -чтения и анализа. Кроме того, написать несколько структурных операторов проще, -чем путаться в похожих именах большого числа меток и мучиться, придумывая -уникальное имя для каждой новой метки. В то же время не запрещается использовать -и метки в любом месте программы. Хорошо поставленная метка способна здорово -облегчить написание и анализ программы. - - Оператор if. - - В общем виде условный оператор можно записать так: - - if(<условие>) - <группа операторов1> - else - <группа операторов2> - - Алгоритм выполнения условного оператора состоит в следующем: -проверяется <условие>, и если оно истинно, то выполняется <группа операторов1>, -следующая за if, после чего управление передается за конец условного оператора. -Если условие ложно, то управление передается на <группу операторов2>, следующую -за else. Порядок выполнения условного оператора в случае отсутствия else -очевиден. В качестве группы операторов может быть либо один оператор, либо блок -из нескольких операторов в {} скобках. Вот несколько примеров: - if(edx<=2){ - WriteStr("Equal or less two\n"); - return(); - } - else{ - WriteStr("Greater than two\n"); - return(0); - } - - if((x<>0)&(y<>0)) - return(x/y); - - Оператор cycle - - Оператор цикла cycle имеет вид: - - cycle(<счетчик>) <группа операторов> - - Цикл выполняется до тех пор пока значение счетчика не будет равно нулю. -Проверка счетчика на равенство нулю и его уменьшение на единицу производится -в конце группы операторов цикла. Допускается внутри цикла использовать и менять -значение счетчика. Если счетчик не указан, то цикл будет бесконечным. Пример: -#import "kernel32.dll" -#import "user32.dll" -dword Count; -dword dWriteFileCount; -dword handle; -byte s[20]=0; -main(){ -handle=GetStdHandle(-11); -Count=4; -cycle(Count){ - if(Count=2) - Count--; - wsprintfA(#s,"Count=%d\n",Count); ESP+=12; - WriteFile(handle,#s,lstrlenA(#s),#dWriteFileCount,0); - } -} - При выполнении будет выведено: -Count=4 -Count=3 -Count=1 - - Оператор while - - Оператор цикла while имеет вид: - - while(<условие>) - <группа операторов> - - Группа операторов в цикле while выполняется пока <условие> остается -истинным. Пример из описания оператора cycle может быть реализован с помощью -while следующим образом: -Count=4; -while(Count){ - if(Count=2) - Count--; - wsprintfA(#s,"Count=%d\n",Count); ESP+=12; - WriteFile(handle,#s,lstrlenA(#s),#dWriteFileCount,0); - Count--; - } -} - - Оператор do ... while - - Оператор цикла do ... while имеет вид: - - do - <группа операторов> - while(<условие>) - - Группа операторов в цикле do ... while выполняется пока <условие> остается -истинным. Пример из описания оператора cycle может быть реализован с помощью -do ... while следующим образом: -Count=4; -do{ - if(Count=2) - Count--; - wsprintfA(#s,"Count=%d\n",Count); ESP+=12; - WriteFile(handle,#s,lstrlenA(#s),#dWriteFileCount,0); - Count--; - } while(Count) -} - Особенностью оператора do ... while является то, что <группа операторов> -в цикле всегда выполняется не менее одного раза. - - Оператор docase - - Оператор ветвления docase имеет вид: - - docase - <группа операторов 0> - case(<условие1>) - <группа операторов 1> - ... - case(<условиеN>) - <группа операторов N> - default - <группа операторов N1> - - Оператор docase позволяет заменить вложенные группы из if ... else if ... -else ... . Кроме того далее будет показана на примере универсальность этого -оператора. Пример из описания оператора cycle может быть реализован с помощью -docase следующим образом: -Count=4; -docase{ - if(Count=2) - Count--; - wsprintfA(#s,"Count=%d\n",Count); ESP+=12; - WriteFile(handle,#s,lstrlenA(#s),#dWriteFileCount,0); - Count--; - case(Count=0) - break; - default - continue; - } -} - - Операторы continue и break - - Эти операторы используются внутри выше описанных операторов цикла cycle, -while, do...while и операторе docase для перехода на начало цикла или docase -по оператору continue и на выход за конец оператора по break. Пример: - while(cond1){<--╘ - ... | - if(cond2) | - continue; --+ - ... | - if(cond3) | - break; ---+ | - ... | | - } ----------|-+ - <----------+ - - Оператор enum - - Назначение оператора заключается в создании групп нумерованных констант. -Пример: - enum { ab, ac=2, ad, ae=6}; при этом будет: ab=0, ac=2, ad=3, ae=6. - - Оператор struc - - Служит для описания структурированных данных, аналогично С. -Пока не реализован. Можно, используя enum, без всяких проблем работать с -данными любой структуры. Пример: -Для использования структуры: -struct localrec{ - struct localrec *next; - char localid[IDLENGTH]; - int localtok; - int localnumber; - }; -создадим: -// ---- Структура localrec - описание локальной переменной -enum{ localnext=0, // Указатель на следующую localrec - localid=4, // Имя локальной переменной - localtok=localid+IDLENGTH, // Значение token - localtype=localtok+4, // тип переменной - localnumber=localtype+4, // Позиция в стеке - local_size=localnumber+4}; // Размер структуры -И теперь в программе можно использовать нумерованные константы для обращения -к элементам структуры localrec: -// ---- Добавить локальную переменную в список -AddLocalvar(dword str,tk,ltype,num) -dword ptr,newptr; -{ -newptr=LocalAlloc(0x40, local_size); -if(newptr==NULL){ - preerror("Compiler out of memory for local symbol linked list"); - ExitProcess(e_outofmemory); - } -if(locallist==NULL) - locallist = newptr; - else{ - ptr = locallist; EBX=ptr; - docase{ - EAX=[EBX+localnext]; - case(EAX!=0){ - EBX=EAX; continue; - } - } - [EBX+localnext]=newptr; - } -EBX=newptr; lstrcpyA(EBX+localid, str); -EBX=newptr; [EBX+localtok] = tk; [EBX+localtype] = ltype; -[EBX+localnumber] = num; [EBX+localnext] = NULL; localptr = EBX; -} - - Метки - - Требования к именам меток те же, что и к идентификаторам. Исключением -являются локальные метки - они должны начинаться с символа '@'. Локальные -метки доступны только в пределах той функции, в которой они определены, а -глобальные - по всей программе. При создании имен локальных меток следует -учитывать, что компилятор при реализации структурных операторов генерирует -метки вида: @l<число>. Чтобы избежать коллизий, следует для своих меток не -применять такого вида. Любая метка завершается символом двоеточия (:). -Примеры меток: - NotUpperCase: // это глобальная метка - @NotUpperCase: // а это локальная метка - - Индексация массивов - - Элементы массива любого типа индексируются в байтовых единицах, независимо -от типа данных. Это ВСЕГДА следует помнить при работе. Индексы имеют вид, -принятый в ассемблере для 386 CPU: - - <переменная>[<базовый регистр>+<масштаб>*<индексный регистр>+<индекс>] - - Вот несколько примеров: - Str[7]; // седьмой байт из массива Str - IntArray[4*ebx]; // ebx элемент из массива целых - IntArray - ByteArray[esi+8*ecx+300]; - - Специальные условные выражения - - Имеется шесть специальных условных выражений: - CarryFlag, NotCarryFlag, Overflow, NotOverflow, ZeroFlag, NotZeroFlag. Они -служат для генерации кода проверяющего состояние флагов CPU. - - Комментарии - - Комментарии задаются аналогично С. - - Директивы компилятора - - Все директивы компилятора начинаются с символа '#'. Список директив и их -назначение приводятся ниже: - #debug // указывает компилятору на необходимость генерации - // отладочной информации для компилируемой программы - #define // определить константу или идентификатор. Пример: - // #define MAXLINES 400 - // #define less < - // #define SetTrue "eax=1" - // if(lines less MAXLINES) --> if(lines<400) - // SetTrue; --> eax=1; - #dll // указывает компилятору на генерацию DLL-файла. Обычно - exe. - #include // подключение файла с исходным текстом. Аналогично С. - #import // импорт функций из DLL-файла по имени. - #importN // импорт функций из DLL-файла по номеру. Пример смотрите в - // описании структурных операторов cycle, while и т.д. - #list // указывает компилятору на генерацию файла с листингом (.lst) - #map // указывает компилятору на генерацию map-файла (.map) - - Встроенный ассемблер - - Ассемблер поддерживает большую часть инструкций из набора 386, 486 и 586 -процессоров. Мнемоники ассемблера могут быть помещены внутри тела любой функции -без каких-либо ограничений. Пример: -// Выделение слова в Dest из строки символов Source -dword GetWord(dword Source,Dest){ - push esi; push edi; esi=Source; edi=Dest; -// Ищем первый непустой символ -@up: lodsb; cmp al,' '; jz @up; // Пробел - cmp al,0; jz @down // Конец строки Source -// Копируем слово в Dest -@up1: stosb; cmp al,0; jz @down; // Конец строки Source - lodsb; cmp al,' '; jnz @up1; // Не пробел - al=0; jmp @up1 // Отметим конец слова -@down: -// Слово выделено и скопировано в Dest - eax=esi-Source; eax--; // Вычислим длину слова - pop edi; pop esi // Восстановим esi и edi -} - - Заключение - - Не все из вышеописанного реализовано. Это обусловлено в первую очередь тем, -что данная версия является предварительной и основной ее целью является -выявление интереса компьютерной общественности к такому компилятору. - Если Вы заинтересовались этим продуктом или у Вас возникли какие-либо -вопросы, идеи или предложения, то прошу о них сообщить мне по адресу: -halimovskiy@usa.net. - - С уважением А.Халимовский E-mail: halimovskiy@usa.net diff --git a/programs/develop/c--/trunk/tokscan.h-- b/programs/develop/c--/trunk/tokscan.h-- deleted file mode 100644 index 807c8a2e8a..0000000000 --- a/programs/develop/c--/trunk/tokscan.h-- +++ /dev/null @@ -1,666 +0,0 @@ -// ---- Преобразование текущего символа для констукций типа: \n, \x00, т.п. -byte ConvertChar() -dword hold; -{ - IF(cha!='\\')return(cha); - NextChar(); // Обработка следующего за \ - IF(AL>='0')&&(AL<='9'){ -// Десятичная константа - EDX=0; - AL-='0'; - EAX=AL; - EDX+=EAX; - ECX=2; - loop(ECX){ - EBX=EDX; - EDX<<=1; - EBX<<=3; - EDX+=EBX; - NextChar(); - EAX=AL; - IF(AL<'0')||(AL>'9')GOTO ERR; - AL-='0'; - EDX+=EAX; - } - return(DL); -ERR: - expectederror("decimal digit"); - return(0); - } - IF(cha=='a')return('\a'); - IF(cha=='b') return('\b'); - IF(cha=='f') return('\f'); - IF(cha=='l') return(10); - IF(cha=='n') return(13); - IF(cha=='p') return('_'); - IF(cha=='r') return(13); - IF(cha=='t') return('\t'); - IF(cha=='v') return('\v'); - IF(cha=='x'){ // HEX константа - ECX=2; - hold=0; - loop(ECX){ - $PUSH ECX; - NextChar(); - CharUpperA(AL); - EBX=AL; - IF(AL>='0')&&(AL<='9')GOTO LX1; - IF(AL<'A')&&(AL>'F')GOTO ERR1; -LX1: - EDX=hold; - EDX<<=4; - IF(BL>='A')BL-='A'-10-'0'; - BL-='0'; - EDX+=EBX; - hold=EDX; - $POP ECX; - } - return(hold); -ERR1: - $POP ECX; - expectederror("hexdecimal digit"); - return(0); - } - return(cha); -} - -// ---- Разделители -byte Delim1={'#','\"','\'','-','+','*','/','%','|','&','!','^','=','>','<','@',0}; -byte Delim2={':',';','(',')','{','}','[',']',',','.','$','?','~',0}; -// ---- Определение типа token -TokScan(dword tok4,type4,src4,post4,string4,number4) -dword useme,strptr; -dword next; -dword dirPrefix,locPrefix;// Флаги обнаружения #directive или @LocalLabel -{ - dirPrefix=0; - locPrefix=0; -SC_0: - strptr=string4; - next=1; - EAX=number4; - DSDWORD[EAX] = 0; - EAX=type4; - DSDWORD[EAX] = 0; - EAX=src4; - DSDWORD[EAX] = 0; - EAX=post4; - DSDWORD[EAX] = 0; - WhiteSpaces(); - ESI=string4; - DSBYTE[ESI]=0; - ECX=17; - EDI=#Delim1; - AL=cha; - $REPNZ $SCASB; - $JCXZ SC00 // Не первая группа разделителе - EDI=EDI-#Delim1-1<<2+#Jmp_Delim1; - $JMP NEAR DSDWORD[EDI]; -SC00: - ECX=14; - EDI=#Delim2; - AL=cha; - $REPNZ $SCASB; - $JCXZ SC01 // Не вторая группа разделителе - EDI=EDI-#Delim2-1+#tk_delim2; - EAX=DSBYTE[EDI]; - EBX=tok4; - DSDWORD[EBX]=EAX; - $JMP ScEx -SC01: - IF(locPrefix){ - EDI>=IDLENGTH){ - preerror("Maximum length for an identifier exceeded"); - strptr = string4 + IDLENGTH - 1; - } - EDI=strptr; - AL=0; - $STOSB - EBX=tok4; - DSDWORD[EBX]=tk_id; - IF(locPrefix)goto FL; - FastSearch(string4,#St_Directives); // Это зарезервированное слово? - IF(CARRYFLAG){ // Команда обнаружена в списке - EBX=number4; DSDWORD[EBX]=EAX; // Запомним порядковый номер - EBX=tok4; // Укажем соответствующий token - IF(dirPrefix)DSDWORD[EBX]=tk_directive; - ELSE DSDWORD[EBX]=tk_command; - dirPrefix=0; - next=0; - $JMP ScEx - } - FastSearch(string4,#St_Mnemonics); // Это мнемоника? - IF(CARRYFLAG){ // Мнемоника ассемблера - EBX=number4; - DSDWORD[EBX]=EAX; // Запомним номер мнемоники - EBX=tok4; - DSDWORD[EBX]=tk_mnemonics; - next=0; - $JMP ScEx - } - FastSearch(string4,#St_Registers); // Это имя регистра? - IF(CARRYFLAG){ // Регистр - EBX=number4; - DSDWORD[EBX]=EAX; // Запомним номер региста - EAX>>=3; - $CMP EAX,2; - $JG R0 // Управляющие регистры? - EBX=tok4; - DSDWORD[EBX]=tk_reg; - EBX=type4; - EAX<<=1; - DSDWORD[EBX] = EAX + tk_byte; - GOTO R1; -R0: - EBX=tok4; - EAX-=3; - DSDWORD[EBX]=EAX+tk_controlreg; -R1: - next=0; - $JMP ScEx - } -FL: - EAX=tok4; - EAX=DSDWORD[EAX]; - IF(AL==tk_id){ - SearchLocals(tok4,type4,string4,number4); // Есть в списке локальных? - EAX=tok4; - EAX=DSDWORD[EAX]; - IF(AL==tk_id){ - IF(locPrefix){ // @label - EBX=tok4; - DSDWORD[EBX]=tk_locallabel; - IF(displaytokerrors)AddLocalvar(#string,tk_locallabel,0,0); - locPrefix=0; - GOTO FL; - } - SearchTree(tok4,type4,src4,post4,string4,number4); - } - } - IF(dirPrefix){ // Конструкция: #ident - dirPrefix=0; - EBX=tok4; - EAX=DSDWORD[EBX]; - IF(AL==tk_id){ // Есть в списке? - IF(displaytokerrors){ - EAX=post4; - DSDWORD[EAX] = 1; // Добавим в список - EBX=tok4; - DSDWORD[EBX]=tk_undefproc; - AddToTree(string4); - } - } - // Идентификатор есть в списке - EAX=post4; - EAX=DSDWORD[EAX]; - EBX=tok4; - IF(EAX){ // Еще не обработанный идентификатор? - DSDWORD[EBX] = tk_postnumber; - } - ELSE{ - EAX=tok4; - EAX=DSDWORD[EAX]; - IF(EAX==tk_param)DSDWORD[EBX] = tk_locnumber; - ELSE IF(EAX==tk_local)DSDWORD[EBX] = tk_locnumber; - ELSE DSDWORD[EBX] = tk_number; - } - } - next=0; - $JMP ScEx - } - else if(IsNumber(cha)){ // Идентификатор начинается с цифры - EAX=tok4; - DSDWORD[EAX]=tokens; // Пока неизвестный token - if(cha=='0'){ - NextChar(); - IF(cha=='X')||(cha=='x'){ // hex - число - EAX=tok4; - DSDWORD[EAX]=tk_number; -HEX: - NextChar(); - CharUpperA(AL); - $CMP AL,'0'; - $JL EHEX; - $CMP AL,'9'; - $JA HEXAF - AL-='0'; - for(;;){ - EBX=number4; - ECX=DSDWORD[EBX]; - ECX<<=4; - EAX+=ECX; - DSDWORD[EBX]=EAX; - GOTO HEX; -HEXAF: - IF(AL<'A')||(AL>'F')BREAK; - AL-='7'; - } -EHEX: - } - ELSE IF(cha=='B')||(cha=='b'){ // binary число - EAX=tok4; - DSDWORD[EAX]=tk_number; - for(;;){ - NextChar(); - IF(AL!='0')||(AL!='1')BREAK; - AL-='0'; - EBX=number4; - ECX=DSDWORD[EBX]; - ECX<<=1; - EAX+=ECX; - DSDWORD[EBX]=EAX; - } -EBIN: - } - ELSE IF(cha=='O')||(cha=='o'){ // octal число - EAX=tok4; - DSDWORD[EAX]=tk_number; - for(;;){ - NextChar(); - IF(AL<'0')||(AL>'7')BREAK; - AL-='0'; - EBX=number4; - ECX=DSDWORD[EBX]; - ECX<<=3; - EAX+=ECX; - DSDWORD[EBX]=EAX; - } -EOCT: - } - } - EAX=tok4; - EAX=DSDWORD[EAX]; - IF(EAX!=tk_number){ // decimal число - for(;;){ - EAX=cha; - IF(AL<'0')||(AL>'9')BREAK; - AL-='0'; - EBX=number4; - EDX=DSDWORD[EBX]; - ECX=EDX; - EDX<<=1; - ECX<<=3; - EDX+=ECX; - EAX+=EDX; - DSDWORD[EBX]=EAX; - NextChar(); - } - EAX=tok4; - DSDWORD[EAX]=tk_number; - } - next=0; - } - ELSE{ - IF(displaytokerrors)preerror("tokenizer: bad character value"); - NextChar(); - TokScan(tok4,type4,src4,post4,string4,number4); - next=0; - } - $JMP ScEx -Jmp_Number: // #directive || #identifier - NextChar(); - dirPrefix=1; - $JMP SC_0 -Jmp_Local: // @LocalLabel - NextChar(); - locPrefix=1; - $JMP SC01 -Jmp_String: // Строка символов в "" - do{ - NextChar(); - IF(cha=='\"') // Закрывающая кавычка - BREAK; - EAX=strptr-string4; - IF(EAX0){ - WhiteSpaces(); - IF( cha == '*' ){ - NextChar(); - IF(cha == '/' ){ // Закрытие комментария - IF(useme > 0)useme--; // Уменишим счетчик - NextChar(); - } - } - ELSE{ - IF( cha == '/' ){ - NextChar(); - IF( cha == '*' ){ // Вложенный комментарий - useme++; - NextChar(); - } - } - ELSE // Не ограничители комментария - NextChar(); - } - } - IF(endoffile){ - EAX=tok4; - DSDWORD[EAX]=tk_eof; - IF(useme > 0)&&(displaytokerrors)unexpectedeof(); - } - ELSE TokScan(tok4,type4,src4,post4,string4,number4); - } - ELSE IF(cha=='/'){ // Комментарий до конца строки // - do{ - NextChar(); - IF(endoffile)BREAK; - } while(cha!=10 ); - IF(endoffile){ - EAX=tok4; - DSDWORD[EAX]=tk_eof; - } - ELSE{ - WhiteSpaces(); - TokScan(tok4,type4,src4,post4,string4,number4); - } - } - ELSE{ - WhiteSpaces(); - IF(cha=='-'){ - EAX=tok4; DSDWORD[EAX]=tk_divminus; // /- - NextChar(); - } - ELSE{ - EAX=tok4; - DSDWORD[EAX]=tk_div; // / - } - } - next = 0; - $JMP ScEx -Jmp_Mod: // % - NextChar(); - WhiteSpaces(); - IF(cha == '-'){ - EAX=tok4; - DSDWORD[EAX] = tk_modminus; // %- - } - ELSE{ - EAX=tok4; - DSDWORD[EAX]=tk_mod; next=0; - } - $JMP ScEx -Jmp_Or: // | - NextChar(); - IF(cha=='='){ - EAX=tok4; - DSDWORD[EAX]=tk_orequals; // |= - } - ELSE IF(cha=='|'){ - EAX=tok4; - DSDWORD[EAX]=tk_oror; // || - } - ELSE{ - WhiteSpaces(); - IF(cha=='-'){ - EAX=tok4; - DSDWORD[EAX]=tk_orminus; // |- - } - ELSE{ - EAX=tok4; - DSDWORD[EAX]=tk_or; - next=0; // | - } - } - $JMP ScEx -Jmp_And: // & - NextChar(); - IF(cha=='='){ - EAX=tok4; - DSDWORD[EAX]=tk_andequals; // &= - } - ELSE IF(cha=='&'){ - EAX=tok4; - DSDWORD[EAX]=tk_andand; // && - } - ELSE{ - WhiteSpaces(); - IF(cha == '-'){ - EAX=tok4; - DSDWORD[EAX]=tk_andminus; // &- - } - ELSE{ - EAX=tok4; - DSDWORD[EAX]=tk_and; - next=0;// & - } - } - $JMP ScEx -Jmp_Not: // ! - NextChar(); - IF(cha == '='){ - EAX=tok4; - DSDWORD[EAX]=tk_notequal; // != - } - ELSE{ - EAX=tok4; - DSDWORD[EAX]=tk_not; - next=0; // ! - } - $JMP ScEx -Jmp_Xor: // ^ - NextChar(); - IF(cha == '='){ - EAX=tok4; - DSDWORD[EAX]=tk_xorequals; // ^= - } - ELSE{ - WhiteSpaces(); - IF(cha == '-'){ - EAX=tok4; - DSDWORD[EAX]=tk_xorminus; // ^- - } - ELSE{ - EAX=tok4; - DSDWORD[EAX]=tk_xor; - next=0; // ^ - } - } - $JMP ScEx -Jmp_Equal: // = - NextChar(); - IF(cha == '='){ - EAX=tok4; - DSDWORD[EAX]=tk_equalto; // == - } - ELSE{ - EAX=tok4; - DSDWORD[EAX]=tk_assign; - next=0; // = - } - $JMP ScEx -Jmp_Great: // > - NextChar(); - IF(cha=='>'){ - NextChar(); - IF( cha == '=' ){ - EAX=tok4; - DSDWORD[EAX]=tk_rrequals; // >>= - } - ELSE{ - WhiteSpaces(); - IF(cha == '-'){ - EAX=tok4; - DSDWORD[EAX]=tk_rrminus; // >>- - } - ELSE{ - EAX=tok4; - DSDWORD[EAX]=tk_rr; - next=0;// >> - } - } - } - ELSE IF(cha=='<'){ - EAX=tok4; - DSDWORD[EAX]=tk_swap; // >< - } - ELSE IF(cha=='='){ - EAX=tok4; - DSDWORD[EAX]=tk_greaterequal; // >= - } - ELSE{ - EAX=tok4; - DSDWORD[EAX]=tk_greater; - next= 0; // > - } - GOTO ScEx; -Jmp_Less: // < - NextChar(); - IF(cha=='<'){ - NextChar(); - IF(cha=='='){ - EAX=tok4; - DSDWORD[EAX]=tk_llequals; // <<= - } - ELSE{ - WhiteSpaces(); - IF(cha == '-'){ - EAX=tok4; - DSDWORD[EAX]=tk_llminus; // <<- - } - ELSE{ - EAX=tok4; - DSDWORD[EAX]=tk_ll; - next=0; - } - } - } - ELSE IF(cha=='>'){ - EAX=tok4; - DSDWORD[EAX]=tk_notequal; // <> - } - ELSE IF(cha=='='){ - EAX=tok4; - DSDWORD[EAX]=tk_lessequal; // <= - } - ELSE{ - EAX=tok4; - DSDWORD[EAX]=tk_less; - next=0; // < - } -ScEx: - IF(next)NextChar(); -} - -// '#','\"','\'','-','+','*','/','%','|','&','!','^','=','>','<','@' -dword Jmp_Delim1={#Jmp_Number,#Jmp_String,#Jmp_Const,#Jmp_Minus, -#Jmp_Plus,#Jmp_Mul,#Jmp_Div,#Jmp_Mod,#Jmp_Or,#Jmp_And, -#Jmp_Not,#Jmp_Xor,#Jmp_Equal,#Jmp_Great,#Jmp_Less,#Jmp_Local}; - -// ':', ';', '(', ')', -byte tk_delim2={tk_colon,tk_semicolon,tk_openbracket,tk_closebracket, -// '{', '}', '[', ']', ',', -tk_openbrace,tk_closebrace,tk_openblock,tk_closeblock,tk_comma, -//'.', '$', '?', '~' -tk_period,tk_dollar,tk_question,tk_tilda}; diff --git a/programs/develop/c--/trunk/tree.h-- b/programs/develop/c--/trunk/tree.h-- deleted file mode 100644 index 0a1661e180..0000000000 --- a/programs/develop/c--/trunk/tree.h-- +++ /dev/null @@ -1,461 +0,0 @@ -// ---- Занесение поименованной константы в список -AddConstToTree(dword keystring,constvalue) -dword ptr,newptr; // idrec structure -{ - newptr=LocalAlloc(0x40,recsize); - IF(EAX==NULL){ - preerror("Compiler out of memory for identifier tree"); - ExitProcess(e_outofmemory); - } - ptr=treestart; - IF(EAX == NULL ) // Пустой список? - treestart = newptr; - ELSE{ - for(;;){ -// Поиск свободной ссылки - ESI=ptr; - EAX=lstrcmpA(DSDWORD[ESI+recid],keystring); - ESI=ptr; - IF(long EAX<0){ - // ptr.left - IF(DSDWORD[ESI+left]==0){ // Нашли пустой левый - добавим - DSDWORD[ESI+left]=newptr; - BREAK; // ptr.left=newptr - } - ptr=DSDWORD[ESI+left]; - } - ELSE IF(EAX!=0){ - // ptr.right - IF(DSDWORD[ESI+right]==0){ // Нашли пустой правый - добавим - DSDWORD[ESI+right]=newptr; - BREAK; - } - ptr=DSDWORD[ESI+right]; - } - ELSE internalerror("string found in tree when trying to add to it"); - } - } -// Формируем новую запись в списке - ESI=newptr; - DSDWORD[ESI+recid]=LocalAlloc(0x40,lstrlenA(keystring)+1); - lstrcpyA(DSDWORD[ESI+recid],keystring); - ESI=newptr; - DSDWORD[ESI+newid]= NULL; - DSDWORD[ESI+rectok]=tk_number; - DSDWORD[ESI+recnumber]=constvalue; - DSDWORD[ESI+recpost]=0; - DSDWORD[ESI+left]=NULL; - DSDWORD[ESI+right]=NULL; - DSDWORD[ESI+recmodline] = currmod<<16+linenumber; -} - -// ---- Добавить локальную переменную в список -AddLocalvar(dword str,tk,ltype,num) -dword newptr; -{ - newptr=LocalAlloc(0x40,local_size); - IF(EAX==NULL){ - preerror("Compiler out of memory for local symbol linked list"); - ExitProcess(e_outofmemory); - } - IF(locallist==NULL)locallist = newptr; - ELSE{ - EAX=locallist; - EBX>>16; - EAX=FILENAMESIZE*EBX+#modules; - EBX=EAX; - wsprintfA(#mapstr,"File:%s, line=%-d:\n%s\n",EBX, - DSDWORD[ESI+recmodline]&0xFFFF,DSDWORD[ESI+recsrc]); - fprint(mapfile,#mapstr); - ESI=ptr; LocalFree(DSDWORD[ESI+recsrc]); // Освободим память - DSDWORD[ESI+recsrc]=0; - } - } - numberofids++; - } - ESI=ptr; - DisplayTreeAll(DSDWORD[ESI+left]); -} -} - -// ---- Вывод списка глобальных констант -DisplayTreeConstants(dword ptr) -{ - IF( ptr != NULL ){ - ESI=ptr; - DisplayTreeConstants(DSDWORD[ESI+right]); - ESI=ptr; - EAX=DSDWORD[ESI+rectok]; - IF(EAX == tk_number){ - wsprintfA(#mapstr,"#define %10ld /* %8lX hex */ %s\n", - DSDWORD[ESI+recnumber],DSDWORD[ESI+recnumber],DSDWORD[ESI+recid]); - fprint(mapfile,#mapstr); - numberofids++; - } - ESI=ptr; - DisplayTreeConstants(DSDWORD[ESI+left]); - } -} - -// ---- Вычисление значения беззнаково константы -dword DoConstDwordMath() -dword value; -{ - IF(tok == tk_minus){ - NextTok(); - IF(tok != tk_number){ - numexpected(); - return(0); - } - number = -number; - } - IF(tok != tk_number){ - numexpected(); - return(0); - } - value = number; - while(tok2isopperand()){ - NextTok(); - IF(tok2!=tk_number)return(value); - switch(tok){ - case tk_minus: value -= number2; break; - case tk_plus: value += number2; break; - case tk_xor: value ^= number2; break; - case tk_and: value &= number2; break; - case tk_or: value |= number2; break; - case tk_mod: value = value % number2; BREAK; - case tk_div: value = value / number2; BREAK; - case tk_mult: value = value * number2; BREAK; - case tk_rr: value >>= number2; BREAK; - case tk_ll: value <<= number2; BREAK; - case tk_xorminus: value ^= -number2; BREAK; - case tk_andminus: value &= -number2; BREAK; - case tk_orminus: value |= -number2; BREAK; -/* case(tok==tk_modminus) value %= -number2; - case(tok==tk_divminus) value /= -number2; - case(tok==tk_multminus) value *= -number2; */ - case tk_rrminus: value >>= -number2; BREAK; - case tk_llminus: value <<= -number2; BREAK; - } - NextTok(); - } - return(value); -} - -// ---- Вычисление значения знаковой константы -long DoConstMath() -long value; -{ - IF(tok == tk_minus){ - NextTok(); - IF(tok != tk_number){ - numexpected(); - return(0); - } - number = -number; - } - IF(tok != tk_number){ - numexpected(); - return(0); - } - value = number; - while(tok2isopperand()){ - NextTok(); - IF(tok2 != tk_number) return(value); - switch(tok){ - case tk_minus: value -= number2; break; - case tk_plus: value += number2; break; - case tk_xor: value ^= number2; break; - case tk_and: value &= number2; break; - case tk_or: value |= number2; break; - case tk_mod: value = value % number2; BREAK; - case tk_div: value = value / number2; BREAK; - case tk_mult: value = value * number2; BREAK; - case tk_rr: value >>= number2; BREAK; - case tk_ll: value <<= number2; BREAK; - case tk_xorminus: value ^= -number2; BREAK; - case tk_andminus: value &= -number2; BREAK; - case tk_orminus: value |= -number2; BREAK; -/* case(tok==tk_modminus) value %= -number2; - case(tok==tk_divminus) value /= -number2; - case(tok==tk_multminus) value *= -number2; */ - case tk_rrminus: value >>= -number2; BREAK; - case tk_llminus: value <<= -number2; BREAK; - } - NextTok(); - } - return(value); -} - -// ---- Вычисление значения знаковой константы -long DoConstLongMath() -long value; -{ - value=DoConstMath(); - NextTok(); - return(value); -} - -// ---- Следующий token - операция? -dword tok2isopperand() -{ - EAX=tok2; - IF(EAX==tk_plus)||(EAX==tk_minus)||(EAX==tk_mult)||(EAX==tk_div)||(EAX==tk_mod)|| - (EAX==tk_rr)||(EAX==tk_ll)||(EAX==tk_or)||(EAX==tk_and)||(EAX==tk_xor)|| - (EAX==tk_divminus)||(EAX==tk_modminus)||(EAX==tk_multminus)||(EAX==tk_xorminus)|| - (EAX==tk_orminus)||(EAX==tk_andminus)||(EAX==tk_llminus)||(EAX==tk_rrminus)return(1); - return(0); -} - -// ---- Следующий token закрывает выражение? -dword tok2notstopper () -{ - EAX=tok2; - IF(EAX==tk_semicolon)||(EAX==tk_comma)||(EAX==tk_closebracket)|| - (EAX==tk_openblock)EAX=0; - ELSE EAX=1; -} - -// ---- Поиск в списке локальных переменных -SearchLocals(dword tok4,type4,string4,number4) -{ - if( locallist != NULL ){ - localptr = locallist; -S00: - ESI=EAX; //localptr; - lstrcmpA(string4,ESI+localid); - ESI=localptr; - IF(EAX==0){ // Переменная найдена - EBX=number4; - DSDWORD[EBX]=DSDWORD[ESI+localnumber]; - EBX=type4; - DSDWORD[EBX]=DSDWORD[ESI+localtype]; - EBX=tok4; - EAX=DSDWORD[ESI+localtok]; - DSDWORD[EBX]=EAX; - IF(EAX==tk_local){ - EBX=number4; - DSDWORD[EBX]-=localsize; - } - ELSE IF(EAX==tk_param){ - EBX=number4; - EAX=DSDWORD[EBX]+4; - DSDWORD[EBX]=EAX; - IF(current_proc_type==cpt_far)DSDWORD[EBX]+=4; // move over seg on stack - } - ELSE IF(EAX!=tk_locallabel)&&(EAX!=tk_number)internalerror("Bad *tok4 value in SearchLocals"); - } - ELSE{ - IF(DSDWORD[ESI+localnext]!=NULL){ - localptr=DSDWORD[ESI+localnext]; - $JMP S00 - } - } - } -} - -// ---- Поиск в списке глобальных идентификаторов -dword SearchTree(dword tok4,type4,src4,post4,string4,number4) -dword ptr; -long cmpresult; -{ - cmpresult=123; - ptr = treestart; -// Поиск свободной ссылки - for(;;){ - ESI=EAX; - IF(ESI==0){ - treeptr=NULL; - return(0); // Not found - } - cmpresult = lstrcmpA(DSDWORD[ESI+recid],string4); - ESI=ptr; - IF(cmpresult<0)ptr=DSDWORD[ESI+left]; - ELSE IF(cmpresult>0)ptr=DSDWORD[ESI+right]; - ELSE BREAK; - } - EBX=number4; DSDWORD[EBX]=DSDWORD[ESI+recnumber]; - EBX=type4; DSDWORD[EBX]=DSDWORD[ESI+rectype]; - EBX=src4; DSDWORD[EBX]=DSDWORD[ESI+recsrc]; - EBX=post4; DSDWORD[EBX]=DSDWORD[ESI+recpost]; - EBX=tok4; EAX=DSDWORD[ESI+rectok]; DSDWORD[EBX]=EAX; - IF(EAX==tk_string ){ - EBX=number4; ECX=DSDWORD[EBX]; EDI=string4; - ESI=DSDWORD[ESI+newid]; $REP $MOVSB - } - ELSE{ - IF(DSDWORD[ESI+newid])lstrcpyA(string4,DSDWORD[ESI+newid]); - } - ESI=ptr; - IF(lstrcmpA(DSDWORD[ESI+recid],string4)!=0) // Проверим: менялось ли имя идентификатора - SearchTree(tok4,type4,src4,post4,string4,number4); // Да - повторим поиск - treeptr = ptr; - return(1); -} - -// ---- Поиск неоткомпилированных еще ссылок -dword SeekToDo(dword ptr) -{ - IF(ptr!=NULL){ - ESI=ptr; - IF(SeekToDo(DSDWORD[ESI+right]))RETURN(1); - ESI=ptr; EAX=DSDWORD[ESI+recpost]; - IF(EAX>1){ - treeptr=ptr; ESI=ptr; - number=DSDWORD[ESI+recnumber]; - type=DSDWORD[ESI+rectype]; modline=DSDWORD[ESI+recmodline]; - src=DSDWORD[ESI+recsrc]; - post=DSDWORD[ESI+recpost]; - tok=DSDWORD[ESI+rectok]; RETURN(1); - } - ESI=ptr; - IF(SeekToDo(DSDWORD[ESI+left]))RETURN(1); - } - return(0); -} - -// ---- Поиск незакрытых ссылок -SeekUndefined(dword ptr) -{ - IF( ptr != NULL ){ - ESI=ptr; - SeekUndefined(DSDWORD[ESI+right]); - ESI=ptr; EAX=DSDWORD[ESI+rectok]; - IF(EAX==tk_undefproc){ - wsprintfA(#mapstr,"'%s' undefined\n",DSDWORD[ESI+recid]); - IF( makemapfile )fprint(mapfile,#mapstr); - WRITESTR(#mapstr); - } - ESI=ptr; - SeekUndefined(DSDWORD[ESI+left]); - } -} - diff --git a/programs/develop/c--/trunk/wapi.h-- b/programs/develop/c--/trunk/wapi.h-- deleted file mode 100644 index 86ccca4902..0000000000 --- a/programs/develop/c--/trunk/wapi.h-- +++ /dev/null @@ -1,36 +0,0 @@ -extern WINAPI "user32.dll" -{ - cdecl long wsprintfA(); - dword IsCharAlphaA(); - dword IsCharAlphaNumericA(); - dword CharUpperA(); - dword CharToOemA(); - -} - -extern WINAPI "kernel32.dll" -{ - long lstrlenA(); - long lstrcmpA(); - dword lstrcpyA(); - dword lstrcpynA(); - dword lstrcatA(); - long _lopen(); - dword _lread(); - dword _lwrite(); - long _llseek(); - long _lclose(); - long _lcreat(); - dword LocalAlloc(); - dword LocalFree(); - dword LocalUnlock(); - dword GetSystemDirectoryA(); - dword GlobalFree(); - dword GetStdHandle(); - dword GetLastError(); - dword GetFileSize(); - dword GetCommandLineA(); - void ExitProcess(); - dword CloseHandle(); - -} \ No newline at end of file