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 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)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