Yet another simple compiler for Linux

Compiler source code listed below may be compiled with Context and FASM but it requires two modifications of source code:

word Digraph(char C1, char C2) is -> word Digraph(char C1; char C2) is word Emi3(word P, word W) is -> word Emi3(word P; word W) is

and adding assignment at the end of begin/end block.

begin ... hFile:=create(); write(); close(); Text[0]:='A'; end

Also you need add in generated assembler listing one rb directive before @@DATA label:

@@TEXT db "Context 2.0 for Linux", 0 rb 6143 @@DATA rb 38580

You must check that offset of Text array in generated executable are 0x0804C000. Use hd, biew or other tool to view hex dump. At the end you must see:

B0 41 ;mov AL, 'A' A2 00 C0 04 08 ;mov [0804C000H], AL 89 EC ;mov ESP, EBP 5D ;pop EBP B8 01 00 00 00 ;mov EAX, 1 31 DB ;xor EBX, EBX CD 80 ;int 80H 43 6F 6E 74 ... ;Context 2.0 for Linux

If offset in second mov command differ, adjust constant in added rb directive and generate new executable.

Compiled program must be placed in file with name c.prg, compiled result are saved in file c.

char Text [16384]; word pText; word nText; word nLine; byte Code [16384]; word nCode; word hFile; char Heap [ 2048]; word nHeap; word Name [ 128]; word Cls [ 128]; word Sub [ 128]; word Type [ 128]; word Size [ 128]; word Ofs [ 128]; word nName; word pData; word nData; word Stk [ 128]; word pStk; char Buff [ 128]; word nBuff; word open() is inline 0xB8, 0x05, 0x00, 0x00, 0x00; // mov EAX, 5 inline 0xBB, 0x54, 0x40, 0x05, 0x08; // mov EBX, @@DATA+Ofs(Heap[64]) inline 0xB9, 0x00, 0x00, 0x00, 0x00; // mov ECX, 0 inline 0xBA, 0x00, 0x00, 0x00, 0x00; // mov EDX, 0 inline 0xCD, 0x80; // int 80H end word create() is inline 0xB8, 0x05, 0x00, 0x00, 0x00; // mov EAX, 5 inline 0xBB, 0x5A, 0x40, 0x05, 0x08; // mov EBX, @@DATA+Ofs(Heap[70]) inline 0xB9, 0x41, 0x02, 0x00, 0x00; // mov ECX, 241H inline 0xBA, 0xFF, 0x01, 0x00, 0x00; // mov EDX, 1FFH inline 0xCD, 0x80; // int 80H end word read() is inline 0xB8, 0x03, 0x00, 0x00, 0x00; // mov EAX, 3 inline 0x8B, 0x1D, 0x10, 0x40, 0x05, 0x08; // mov EBX, dword [@@DATA+Ofs(hFile)] inline 0xB9, 0x00, 0xC0, 0x04, 0x08; // mov ECX, @@DATA+Ofs(Text) inline 0xBA, 0x00, 0x40, 0x00, 0x00; // mov EDX, 16384 inline 0xCD, 0x80; // int 80H end word write() is inline 0xB8, 0x04, 0x00, 0x00, 0x00; // mov EAX, 4 inline 0x8B, 0x1D, 0x10, 0x40, 0x05, 0x08; // mov EBX, dword [@@DATA+Ofs(hFile)] inline 0xB9, 0x0C, 0x00, 0x05, 0x08; // mov ECX, @@DATA+Ofs(Code) inline 0x8B, 0x15, 0x0C, 0x40, 0x05, 0x08; // mov EDX, dword [@@DATA+Ofs(nCode)] inline 0xCD, 0x80; // int 80H end word close() is inline 0xB8, 0x06, 0x00, 0x00, 0x00; // mov EAX, 6 inline 0x8B, 0x1D, 0x10, 0x40, 0x05, 0x08; // mov EBX, dword [@@DATA+Ofs(hFile)] inline 0xCD, 0x80; // int 80H end word Init() is Heap[ 0]:='0'; Heap[ 1]:='1'; Heap[ 2]:='2'; Heap[ 3]:='3'; Heap[ 4]:='4'; Heap[ 5]:='5'; Heap[ 6]:='6'; Heap[ 7]:='7'; Heap[ 8]:='8'; Heap[ 9]:='9'; Heap[10]:='A'; Heap[11]:='B'; Heap[12]:='C'; Heap[13]:='D'; Heap[14]:='E'; Heap[15]:='F'; Heap[16]:='c'; Heap[17]:='h'; Heap[18]:='a'; Heap[19]:='r'; Heap[20]:= char(0); Heap[21]:='b'; Heap[22]:='y'; Heap[23]:='t'; Heap[24]:='e'; Heap[25]:= char(0); Heap[26]:='w'; Heap[27]:='o'; Heap[28]:='r'; Heap[29]:='d'; Heap[30]:= char(0); Heap[31]:='b'; Heap[32]:='e'; Heap[33]:='g'; Heap[34]:='i'; Heap[35]:='n'; Heap[36]:= char(0); Heap[37]:='i'; Heap[38]:='f'; Heap[39]:= char(0); Heap[40]:='w'; Heap[41]:='h'; Heap[42]:='i'; Heap[43]:='l'; Heap[44]:='e'; Heap[45]:= char(0); Heap[46]:='i'; Heap[47]:='n'; Heap[48]:='l'; Heap[49]:='i'; Heap[50]:='n'; Heap[51]:='e'; Heap[52]:= char(0); Heap[53]:='r'; Heap[54]:='e'; Heap[55]:='t'; Heap[56]:='u'; Heap[57]:='r'; Heap[58]:='n'; Heap[59]:= char(0); Heap[60]:='e'; Heap[61]:='n'; Heap[62]:='d'; Heap[63]:= char(0); Heap[64]:='c'; Heap[65]:='.'; Heap[66]:='p'; Heap[67]:='r'; Heap[68]:='g'; Heap[69]:= char(0); Heap[70]:='c'; Heap[71]:= char(0); nHeap :=72; Name[ 0]:=16; Cls [ 0]:= 1; Size[ 0]:= 1; Name[ 1]:=21; Cls [ 1]:= 1; Size[ 1]:= 1; Name[ 2]:=26; Cls [ 2]:= 1; Size[ 2]:= 4; nName := 3; pStk := 0; nCode := 0; pData := 0x0804C000; nData := pData; end word Push(word V) is Stk[pStk]:=V; pStk:=pStk+1; end word Pop () is pStk:=pStk-1; return Stk[pStk]; end word Stop() is close(); pStk:=0; while nLine!=0 do Push (nLine%10); nLine:=nLine/10; end nBuff:=0; while pStk!=0 do Buff[nBuff]:=char(Pop()+48); nBuff :=nBuff+1; end Buff[nBuff] :=char(0x0A); nBuff :=nBuff+1; inline 0xB8, 0x04, 0x00, 0x00, 0x00; // mov EAX, 4 inline 0xBB, 0x01, 0x00, 0x00, 0x00; // mov EBX, 1 inline 0xB9, 0x28, 0x56, 0x05, 0x08; // mov ECX, @@DATA+Ofs(Buff) inline 0x8B, 0x15, 0xA8, 0x56, 0x05, 0x08; // mov EDX, dword [@@DATA+Ofs(nBuff)] inline 0xCD, 0x80; // int 80H inline 0xB8, 0x01, 0x00, 0x00, 0x00; // mov EAX, 1 inline 0xBB, 0x01, 0x00, 0x00, 0x00; // mov EBX, 1 inline 0xCD, 0x80; // int 80H end word val () is word E:=10; word I:= 0; if Buff[0]='0' then if Buff[1]='x' then E:=16; I:= 2; end end word N:=0; while Buff[I]!=char(0) do word K:=0; while Heap[K]!=Buff[I] do if K=E then Stop(); end K:=K+1; end N:=E*N; N:=N+K; I:=I+1; end return N; end char Look() is if pText>=nText then pText :=0; nText :=read(); if pText>=nText then return char(0); end end return Text[pText]; end char Read() is char Ch:=Look(); if Ch =char(10) then nLine :=nLine+1; end pText :=pText+1; return Ch; end word isalnum() is if 'A'<=Look() then if Look()<='Z' then return 0; end end if 'a'<=Look() then if Look()<='z' then return 0; end end if '0'<=Look() then if Look()<='9' then return 0; end end return 1; end word Digraph(char C1, char C2) is if Buff[0]=C1 then if Look()=C2 then Buff[1]:=Read(); Buff[2]:=char(0); end end end char Scan() is word pBuff:=0; while pBuff =0 do word sFlag:=0; while sFlag =0 do if Look()!=char( 9) then if Look()!=char(10) then if Look()!=char(13) then if Look()!=char(32) then sFlag:=1; end end end end if sFlag=0 then Read(); end end while isalnum()=0 do Buff[pBuff]:= Read(); pBuff :=pBuff+1; end if pBuff=0 then Buff[pBuff]:= Read(); pBuff :=pBuff+1; end Buff[pBuff] :=char(0); Digraph('<', '='); Digraph('!', '='); Digraph('>', '='); Digraph(':', '='); if Buff[0]='/' then if Look()='/' then while Look()!=char(10) do if Read()=char(0) then Stop(); end end pBuff:=0; end end end end word Comp(word pHeap) is word pBuff:=0; while Buff[pBuff]=Heap[pHeap] do if Buff[pBuff]=char(0) then return 0; end pHeap:=pHeap+1; pBuff:=pBuff+1; end return 1; end word Find(word fFlag) is word pName:=0; while pName< nName do if Comp(Name[pName])=0 then return pName; end pName:=pName+1; end if fFlag=0 then Stop(); end return pName; end byte Emi1(byte B) is Code[nCode]:=B; nCode:=nCode+1; end word Emi2(word W) is word P :=0; while P <4 do Emi1(W%256); W :=W/256; P :=P+1; end end word Emi3(word P, word W) is word N :=P+4; while P <N do Code[P]:=W%256; W :=W/256; P :=P+1; end end word Assign(word I) is if Size[I]>1 then Emi1(0x5B); // pop EBX end byte B:=0x89; // mov [(EBX+)Ofs], EAX if Size[Type[I]]=1 then B:=0x88; // mov [(EBX+)Ofs], AL end Emi1(B); B:=0x05; // [Ofs] if Size[I]>1 then B:=0x83; // [EBX+Ofs] end Emi1(B); Emi2(Ofs[I]); end word Expr() is word eFlag:=0; //if eFlag =0 then if '0'<=Buff[0] then if Buff[0]<='9' then Emi1(0xB8); // mov EAX, Val Emi2(val()); eFlag:=1; end end if Buff[0]=''' then Emi1(0xB8); // mov EAX, Val Emi2(word(Read())); Read(); eFlag:=1; end if Buff[0]='(' then Scan(); Expr(); eFlag:=1; end //end if eFlag =0 then word I:=Find(0); if Cls[I]=1 then Push(I); Scan(); // ( Scan(); Expr(); I:=Pop(); end if Cls[I]=2 then if Size[I]>1 then Push(I); Scan(); // [ Scan(); Expr(); I:=Pop(); if Size[Type[I]]=4 then Emi1(0xC1); // shl EAX, 2 Emi1(0xE0); Emi1(0x02); end Emi1(0x93); // xchg EBX, EAX end byte B:=0x8B; // mov EAX, [(EBX+)Ofs] if Size[Type[I]]=1 then Emi1(0x33); // xor EAX, EAX Emi1(0xC0); B:=0x8A; // mov AL, [(EBX+)Ofs] end Emi1(B); B:=0x05; // [Ofs] if Size[I]>1 then B:=0x83; // [EBX+Ofs] end Emi1(B); Emi2(Ofs[I]); end if Cls[I]=3 then Scan(); // ( Push(I); Sub[nName]:= 0; word J:=I+1; while Sub[J]=1 do Push(J); Scan(); Expr(); J:=Pop(); Assign(J); J:=J+1; end I:=Pop(); if J=I+1 then Scan(); // ) end word W:=(0xFFFFFFFF-((nCode+5)-Ofs[I]))+1; Emi1(0xE8); // call Ofs Emi2(W); end end Scan(); word I:=0; if Buff[0]='+' then I:=1; end if Buff[0]='-' then I:=2; end if Buff[0]='*' then I:=3; end if Buff[0]='/' then I:=4; end if Buff[0]='%' then I:=5; end if I!=0 then Emi1(0x50); // push EAX Push(I); Scan(); Expr(); I:=Pop(); Emi1(0x5B); // pop EBX if I =1 then Emi1(0x03); // add EAX, EBX Emi1(0xC3); end if I =2 then Emi1(0x93); // xchg EBX, EAX Emi1(0x2B); // sub EAX, EBX Emi1(0xC3); end if I =3 then Emi1(0xF7); // mul EBX Emi1(0xE3); end if I>=4 then Emi1(0x93); // xchg EBX, EAX Emi1(0x33); // xor EDX, EDX Emi1(0xD2); Emi1(0xF7); // div EBX Emi1(0xF3); end if I =5 then Emi1(0x92); // xchg EDX, EAX end end end word Cond() is Scan(); Expr(); word jCode:=0; if Buff[0]='<' then jCode:=0x83; // jae Ofs if Buff[1]='=' then jCode:=0x87; // ja Ofs end end if Buff[0]='=' then jCode:=0x85; // jne Ofs end if Buff[0]='!' then jCode:=0x84; // je Ofs end if Buff[0]='>' then jCode:=0x86; // jbe Ofs if Buff[1]='=' then jCode:=0x82; // jb Ofs end end if jCode=0 then Stop(); end Emi1(0x50); // push EAX Scan(); Expr(); Emi1(0x5B); // pop EBX Emi1(0x3B); // cmp EBX, EAX Emi1(0xD8); Push(nCode); Emi1(0x0F); // jxx Ofs Emi1(jCode); Emi2(0x00); end word qFlag; word Quit() is if qFlag=1 then Emi1(0xB8); // mov EAX, 1 Emi2(0x01); Emi1(0xBB); // mov EBX, 0 Emi2(0x00); Emi1(0xCD); // int 80H Emi1(0x80); end if qFlag=0 then Emi1(0xC3); // retn end end word Obj (word T) is if Cls[T]!=1 then Stop(); end Name[nName]:=nHeap; Type[nName]:= T; Scan(); if Find(1)<nName then Stop(); end word pBuff:=0; char Ch :=char(1); while Ch !=char(0) do Ch := Buff[pBuff]; Heap[nHeap]:= Ch; nHeap :=nHeap+1; pBuff :=pBuff+1; end Scan(); return nName; end char Var (word Subclass) is Cls [nName]:= 2; Sub [nName]:= Subclass; Size[nName]:= 1; Ofs [nName]:=nData; if Buff[0]='[' then if Subclass!=0 then Stop(); end Scan(); Size[nName]:=val(); Scan(); // ] Scan(); // ; end nData :=nData+(Size[Type[nName]]*Size[nName]); while nData%4!=0 do nData :=nData+1; end nName :=nName+1; return Buff[0]; end word Hide() is word I:=Pop(); while I< nName do Heap[Name[I]]:=char(0); I :=I+1; end end word rFlag; word Ctrl() is word cFlag:=0; //if cFlag =0 then if Comp(37)=0 then // if Cond(); Push(nName); Scan(); Ctrl(); while Comp(60)!=0 do // !end Ctrl(); end Hide(); word pSkip:=Pop(); Emi3(pSkip+2, (nCode-pSkip)-6); rFlag:=1; // 14.05.2006 cFlag:=1; end //end if cFlag =0 then if Comp(40)=0 then // while Push(nCode); Cond(); Push(nName); Scan(); Ctrl(); while Comp(60)!=0 do // !end Ctrl(); end Hide(); word pExit:=Pop (); word pLoop:=Pop (); Emi1(0xE9); // jmp Ofs Emi2((0xFFFFFFFF-((nCode+4)-pLoop))+1); Emi3(pExit+2, (nCode-pExit)-6); rFlag:=1; // 14.05.2006 cFlag:=1; end end if cFlag =0 then if Comp(46)=0 then // inline Buff[0]:=','; while Buff[0]=',' do Scan(); Emi1(val()); // db Val Scan(); end rFlag:=1; // 14.05.2006 cFlag:=1; end end if cFlag =0 then if Comp(53)=0 then // return Scan(); Expr(); Quit(); rFlag:=0; cFlag:=1; end end if cFlag =0 then word I:=Find(0); if Cls[I]=1 then word N:=Obj(I); if Var(2)=':' then Scan(); Expr(); Assign(N); end end if Cls[I]=2 then if Size[I]>1 then Scan(); // [ Scan(); Expr(); if Size[Type[I]]=4 then Emi1(0xC1); // shl EAX, 2 Emi1(0xE0); Emi1(0x02); end Emi1(0x50); // push EAX end Scan(); // := Scan(); Expr(); Assign(I); end if Cls[I]=3 then Expr(); end rFlag:=1; // 14.05.2006 end Scan(); end word Func() is Scan(); Ctrl(); while Comp(60)!=0 do // !end Ctrl(); end if rFlag!=0 then // 14.05.2006 // if rFlag=0 then Quit(); end end word Head(word EP) is Code[0x00]:=0x7F; Code[0x01]:=byte('E'); Code[0x02]:=byte('L'); Code[0x03]:=byte('F'); Code[0x04]:=0x01; // 32bit Code[0x05]:=0x01; // LSB Code[0x06]:=0x01; // Version Code[0x10]:=0x02; // ET_EXEC Code[0x12]:=0x03; // EM_386 Code[0x14]:=0x01; // Version Emi3(0x18, EP); // Entry point Code[0x1C]:=0x34; // e_phofs Code[0x28]:=0x34; // e_ehentsize Code[0x2A]:=0x20; // e_phentsize Code[0x2C]:=0x02; // e_phnum Code[0x2E]:=0x28; // e_shentsize Code[0x34]:=0x01; // PT_LOAD Code[0x38]:=0x74; // Ofs Code[0x3C]:=0x74; // VA Code[0x3D]:=0x80; Code[0x3E]:=0x04; Code[0x3F]:=0x08; Code[0x40]:=Code[0x3C]; // PhA Code[0x41]:=Code[0x3D]; Code[0x42]:=Code[0x3E]; Code[0x43]:=Code[0x3F]; Emi3(0x44, nCode-0x74); // Size Emi3(0x48, nCode-0x74); // Size in memory Code[0x4C]:=0x05; // p_flags //Code[0x50]:=0x00; // p_align Code[0x51]:=0x10; Code[0x54]:=0x01; // PT_LOAD Emi3(0x58, nCode); // Ofs Code[0x5C]:=0x00; // VA Code[0x5D]:=0xC0; Code[0x5E]:=0x04; Code[0x5F]:=0x08; Code[0x60]:=Code[0x5C]; // PhA Code[0x61]:=Code[0x5D]; Code[0x62]:=Code[0x5E]; Code[0x63]:=Code[0x5F]; Emi3(0x68, nData-pData); // Size in memory Code[0x6C]:=0x06; // p_flags //Code[0x70]:=0x00; // p_align Code[0x71]:=0x10; end begin Init(); hFile:=open(); pText:=0; nText:=0; nLine:=1; qFlag:=0; while nCode<0x74 do Emi1(0x00); end Scan(); while Comp(31)!=0 do // !begin Obj (Find(0)); char Ch:=Buff[0]; if Ch ='(' then Cls [nName]:= 3; Sub [nName]:= 0; Ofs [nName]:=nCode; nName :=nName+1; Push(nName); Scan(); // ) if Buff[0]!=')' then Obj (Find(0)); while Var(1)=',' do Scan(); Obj (Find(0)); end end Scan(); // is Func(); Hide(); end if Ch!='(' then Var(0); end Scan(); end word EP:=nCode+0x08048000; qFlag:=1; Func (); Head (EP); close(); hFile:=create(); write(); close(); end



Сайт создан в системе uCoz