Еще один простой компилятор для Linux/AMD64

Приведенный здесь 64-х разрядный компилятор языка TinyContext является аналогом 32-х разрядного компилятора TinyContext и может быть скомпилирован с его помощью. Для этого нужно в приведенном тексте заменить все функции ввода-вывода 32-х разрядными аналогами и получить кросс-компилятор. Затем с его помощью получить 64-х разрядный компилятор.

К сожалению, в отличие от версий для других платформ, объем исходного текста превышает 1000 строк.

Компилируемая программа должна помещаться в файл с именем c.prg, результат компиляции записывается в файл с именем 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, 0x02, 0x00, 0x00, 0x00; // mov RAX, 2 inline 0xBF, 0x68, 0x40, 0x05, 0x08; // mov RDI, @@DATA+Ofs(Heap[64]) inline 0xBE, 0x00, 0x00, 0x00, 0x00; // mov RSI, 0 inline 0xBA, 0x00, 0x00, 0x00, 0x00; // mov RDX, 0 inline 0x0F, 0x05; // syscall end word create() is inline 0xB8, 0x02, 0x00, 0x00, 0x00; // mov RAX, 2 inline 0xBF, 0x6E, 0x40, 0x05, 0x08; // mov RDI, @@DATA+Ofs(Heap[70]) inline 0xBE, 0x41, 0x02, 0x00, 0x00; // mov RSI, 241H inline 0xBA, 0xED, 0x01, 0x00, 0x00; // mov RDX, 1EDH inline 0x0F, 0x05; // syscall end word read() is inline 0xB8, 0x00, 0x00, 0x00, 0x00; // mov RAX, 0 inline 0xBB, 0x20, 0x40, 0x05, 0x08; // mov RBX, @@DATA+Ofs(hFile) inline 0x48, 0x8B, 0x3B; // mov RDI, qword [RBX] inline 0xBE, 0x00, 0xC0, 0x04, 0x08; // mov RSI, @@DATA+Ofs(Text) inline 0xBA, 0x00, 0x40, 0x00, 0x00; // mov RDX, 16384 inline 0x0F, 0x05; // syscall end word write() is inline 0xB8, 0x01, 0x00, 0x00, 0x00; // mov RAX, 1 inline 0xBB, 0x20, 0x40, 0x05, 0x08; // mov RBX, @@DATA+Ofs(hFile) inline 0x48, 0x8B, 0x3B; // mov RDI, qword [RBX] inline 0xBE, 0x18, 0x00, 0x05, 0x08; // mov RSI, @@DATA+Ofs(Code) inline 0xBB, 0x18, 0x40, 0x05, 0x08; // mov RBX, @@DATA+Ofs(nCode) inline 0x48, 0x8B, 0x13; // mov RDX, qword [RBX] inline 0x0F, 0x05; // syscall end word close() is inline 0xB8, 0x03, 0x00, 0x00, 0x00; // mov RAX, 3 inline 0xBB, 0x20, 0x40, 0x05, 0x08; // mov RBX, @@DATA+Ofs(hFile) inline 0x48, 0x8B, 0x3B; // mov RDI, qword [RBX] inline 0x0F, 0x05; // syscall end word puts() is inline 0xB8, 0x01, 0x00, 0x00, 0x00; // mov RAX, 1 inline 0xBF, 0x01, 0x00, 0x00, 0x00; // mov RDI, 1 inline 0xBE, 0x50, 0x64, 0x05, 0x08; // mov RSI, @@DATA+Ofs(Buff) inline 0xBB, 0xD0, 0x64, 0x05, 0x08; // mov RBX, @@DATA+Ofs(nBuff) inline 0x48, 0x8B, 0x13; // mov RDX, qword [RBX] inline 0x0F, 0x05; // syscall end word halt() is inline 0xB8, 0x3C, 0x00, 0x00, 0x00; // mov RAX, 3CH inline 0xBF, 0x01, 0x00, 0x00, 0x00; // mov RDI, 1 inline 0x0F, 0x05; // syscall 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]:= 8; nName := 3; pStk := 0; nCode := 0; pData := 0x0804C000; nData := pData; end word OpenSrc() is hFile:=open(); pText:=0; nText:=0; nLine:=1; end word CloseSrc() is close(); 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 CloseSrc(); 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; puts(); halt(); 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 if nCode>=16384 then Stop(); end Code[nCode]:=B; nCode:=nCode+1; end word Emi2(word W, word N) is word P :=0; while P <N do Emi1(W%256); W :=W/256; P :=P+1; end end word Emi3(word P, word W, word N) is word Q :=P+N; while P <Q do Code[P]:=W%256; W :=W/256; P :=P+1; end end byte EmiP(byte B) is Emi1(0x48); // 64 bit prefix Emi1(B); end word LdIX(word I) is if Ofs[I]<=0xFFFFFFFF then Emi1(0xBB); // mov RBX, Ofs Emi2(Ofs[I], 4); end if Ofs[I]> 0xFFFFFFFF then EmiP(0xBB); // mov RBX, Ofs Emi2(Ofs[I], 8); end end word Assign(word I) is if Size[I]>1 then Emi1(0x5B); // pop RBX end if Size[I]=1 then LdIX(I); end if Size[Type[I]]>1 then EmiP(0x89); // mov [RBX], RAX end if Size[Type[I]]=1 then Emi1(0x88); // mov [RBX], AL end Emi1(0x03); end word Expr() is word eFlag:=0; //if eFlag =0 then if '0'<=Buff[0] then if Buff[0]<='9' then word W:=val(); if W<=0xFFFFFFFF then Emi1(0xB8); // mov RAX, Val Emi2(val(), 4); end if W> 0xFFFFFFFF then EmiP(0xB8); // mov RAX, Val Emi2(val(), 8); end eFlag:=1; end end if Buff[0]=''' then Emi1(0xB8); // mov RAX, Val Emi2(word(Read()), 4); 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]]>1 then EmiP(0xC1); // shl RAX, 3 Emi1(0xE0); Emi1(0x03); end end LdIX(I); if Size[I]>1 then EmiP(0x03); // add RBX, RAX Emi1(0xD8); end if Size[Type[I]]>1 then EmiP(0x8B); // mov RAX, [RBX] Emi1(0x03); end if Size[Type[I]]=1 then EmiP(0x33); // xor RAX, RAX Emi1(0xC0); Emi1(0x8A); // mov AL, [RBX] Emi1(0x03); end 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, 4); 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 RAX Push(I); Scan(); Expr(); I:=Pop(); Emi1(0x5B); // pop RBX if I =1 then EmiP(0x03); // add RAX, RBX Emi1(0xC3); end if I =2 then EmiP(0x93); // xchg RBX, RAX EmiP(0x2B); // sub RAX, RBX Emi1(0xC3); end if I =3 then EmiP(0xF7); // mul RBX Emi1(0xE3); end if I>=4 then EmiP(0x93); // xchg RBX, RAX EmiP(0x33); // xor RDX, RDX Emi1(0xD2); EmiP(0xF7); // div RBX Emi1(0xF3); end if I =5 then EmiP(0x92); // xchg RDX, RAX 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 RAX Scan(); Expr(); Emi1(0x5B); // pop RBX EmiP(0x39); // cmp RBX, RAX Emi1(0xC3); Push(nCode); Emi1(0x0F); // jxx Ofs Emi1(jCode); Emi2(0x00, 4); end word qFlag; word Quit() is if qFlag=1 then EmiP(0xC7); // mov RAX, 03CH Emi1(0xC0); Emi2(0x3C, 4); EmiP(0xC7); // mov RDI, 0 Emi1(0xC7); Emi2(0x00, 4); Emi1(0x0F); // syscall Emi1(0x05); 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%8!=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, 4); 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, 4); Emi3(pExit+2, (nCode-pExit)-6, 4); 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]]>1 then EmiP(0xC1); // shl RAX, 3 Emi1(0xE0); Emi1(0x03); end LdIX(I); EmiP(0x03); // add RAX, RBX Emi1(0xC3); Emi1(0x50); // push RAX 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 ReserveHdr() is while nCode<0xB0 do Emi1(0x00); end end word FillHdr(word EP) is Code[0x00]:=0x7F; Code[0x01]:=byte('E'); Code[0x02]:=byte('L'); Code[0x03]:=byte('F'); Code[0x04]:=0x02; // 64bit Code[0x05]:=0x01; // LSB Code[0x06]:=0x01; // Version Code[0x10]:=0x02; // ET_EXEC Code[0x12]:=0x3E; // EM_X86_64 Code[0x14]:=0x01; // Version Emi3(0x18, EP, 8); // Entry point Code[0x20]:=0x40; // e_phofs Code[0x28]:=0x00; // e_shofs Code[0x30]:=0x00; // e_flags Code[0x34]:=0x40; // e_ehsize Code[0x36]:=0x38; // e_phentsize Code[0x38]:=0x02; // e_phnum Code[0x3A]:=0x40; // e_shentsize Code[0x3C]:=0x00; // e_shnum Code[0x3E]:=0x00; // e_shstrndx Code[0x40]:=0x01; // PT_LOAD Code[0x44]:=0x05; // p_flags Code[0x48]:=0xB0; // p_offset Code[0x50]:=0xB0; // p_vaddr Code[0x51]:=0x80; Code[0x52]:=0x04; Code[0x53]:=0x08; Code[0x58]:=Code[0x50]; // p_paddr Code[0x59]:=Code[0x51]; Code[0x5A]:=Code[0x52]; Code[0x5B]:=Code[0x53]; Emi3(0x60,nCode-0xB0,8); // p_filesz Emi3(0x68,nCode-0xB0,8); // p_memsiz Code[0x70]:=0x00; // p_align Code[0x71]:=0x10; Code[0x78]:=0x01; // PT_LOAD Code[0x7C]:=0x06; // p_flags Emi3(0x80, nCode, 8); // p_offset Code[0x88]:=0x00; // p_vaddr Code[0x89]:=0xC0; Code[0x8A]:=0x04; Code[0x8B]:=0x08; Code[0x90]:=Code[0x88]; // p_paddr Code[0x91]:=Code[0x89]; Code[0x92]:=Code[0x8A]; Code[0x93]:=Code[0x8B]; //Emi3(0x98,nData-pData,8);// p_filesz Emi3(0xA0,nData-pData,8);// p_memsz Code[0xA8]:=0x00; // p_align Code[0xA9]:=0x10; end word WriteBin() is hFile:=create(); write(); close(); end word Compile() is OpenSrc(); qFlag:=0; ReserveHdr(); 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 (); FillHdr(EP); CloseSrc(); WriteBin(); end begin Init(); Compile(); end

32-х разрядные функции ввода-вывода для кросс-компилятора

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, 0xED, 0x01, 0x00, 0x00; // mov EDX, 1EDH 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 puts() is 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 end word halt() is inline 0xB8, 0x01, 0x00, 0x00, 0x00; // mov EAX, 1 inline 0xBB, 0x01, 0x00, 0x00, 0x00; // mov EBX, 1 inline 0xCD, 0x80; // int 80H end


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