Исходный текст программы компилятора




 

#include<stdio.h>;

#include<string.h>;

#include<stdlib.h>;

#include<ctype.h>;

#include<conio.h>;

#include<io.h>;i, c, npr, seg, cnt, pmdf, psym, stk[80], pole[4] [8];

//npr - номер прохода, seg - номер сегмента, cnt - счетчик размещения команд

//pmdf - указатель на конец записи модификатора, psym - указатель на конец

// таблицы меток, stk - сюда считывается строка, pole - поля полученные из

// считанной строки.optab[8] [4]={{«mov»}, {«neg»}, {«je\0»}, {«inc»}, // таблица

{«shl»}, {«adc»}, {«int»}, {«dw\0»}}, // мнемокодов[8] [3]={{«ax»}, {«cx»}, {«dx»}, {«bx»}, // таблицы обозначений

{«sp»}, {«bp»}, {«si»}, {«di»}}, // регистров и[4] [3]={{«es»}, {«cs»}, {«ss»}, {«ds»}}, // сегментных регистров[17]={«0123456789abcdef»},[20]; // таблица модификаторов

struct segt {

char name[8];len;

};segtab[2]; // таблица сегментовsymt {name[8];sgm;dsp;

};symtab[10]; // таблица метокstk2pol (char st[80], char pol[4] [8]); // разбиение строки на поляfindop (char op[8]); // поиск мнемокода в OPTABop2code (char nmb, char dis, char pol[4] [8], char code[4]);

// на входе мнемокод, на выходе длинна команды и объектный кодfindreg (char reg[8]); // поиск обознач. регистра в REGTABfindsegr (char reg[8]); // поиск обознач. сег. регистра в SEGRTAB

char findsym (char sym[8]); // поиск метки в SYMTAB

int str2num (char str[8]); // перевод строки в соотв. числоfindch (char c); // поиск поиск символа в HEXTAB

int step (int a, int b); // возведение A в степень B

int main()

{cod[4], lent, // код и длинна команды; // номер обработчика команды* ft; // исходный ассемблерный файлfn[]={«myprim.asm»};

ft=fopen (fn, «r+»);();

////////////////////////////first passage\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\(» *** first passage *** \n»);

seg=0;=0;=0;(! feof(ft)) // повторять пока не конец файла

{fgets (stk, 80, ft); // чтение строки(«\n»);();(stk);pol (stk, pole); // разбиение строки на поля

if (! strcmp (pole[1], «segment»)) //if второе поле SEGMENT

{seg++; // увеличение номера сегмента, запись=0; // названия в SEGTAB, сброс счетчика

strcpy (segtab [seg-1].name, pole[0]); // размещения;

}(! strcmp (pole[1], «ends»)) //if ENDS, то запись длинны сегм-та

{segtab [seg-1].len=cnt;(«add to segtab:%s % d % d\n»,[seg-1].name, seg, segtab [seg-1].len);;

}((! strcmp (pole[0], «assume»))||(! strcmp (pole[0], "\0»)))

continue; //if пустое поле-чтение сл. строки=findop (pole[0]);(num) //if код операции - увеличение

{lent=op2code (num, 0, pole, cod); // счет. размещ. на ее длинну

if (lent) {printf («lenght:%d\n», lent);+=lent;

}printf («Error: wrong operand!\n»);;

}((pole[0] [strlen (pole[0]) - 1]==':')||(! strcmp (pole[1], «dw»)))

{if (pole[0] [strlen (pole[0]) - 1]==':')[0] [strlen (pole[0]) - 1]='\0'; //if метка(findsym (pole[0])==-1) // не найдена в SYMTAB

{strcpy (symtab[psym].name, pole[0]); // занесение в SYMTAB[psym].sgm=seg;[psym].dsp=cnt;(«add to symtab:%s % d % d\n»,[psym].name, symtab[psym].sgm, symtab[psym].dsp);++;

} //if метка найдена - ошибкаprintf («Error: label % s retry!\n», pole[0]); (! strcmp(pole[1], "\0»)) continue;=findop (pole[1]);

if (num) //if код операции - увеличение

{lent=op2code (num, 1, pole, cod); // счет. размещ. на ее длинну

if (lent) {printf («lenght:%d\n», lent);+=lent;

}printf («Error: wrong operand!\n»);

}printf («Error: wrong mnemonic code!\n»);

} // во всех др. случаях - ошибка

}

////////////////////////////second passage\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* ftmp; // временные файлыfname[2] [10]={{«temp1.dat»}, {«temp2.dat»}};();();(» *** second passage *** \n»);=0;++;=0;(ft);

while (! feof(ft)) // повторять пока не конец файла

{fgets (stk, 80, ft); // чтение строки(«\n»);();(stk);pol (stk, pole); // разбиение строки на поля

if (! strcmp (pole[1], «segment»)) //if второе поле SEGMENT

{seg++; // увеличение номера сегмента=fopen (fname [seg-1], «w+b»); // открыть соотв. вр. файл=0; // сброс счетчика размещения;

}(! strcmp (pole[1], «ends»)) //if ENDS-заткрыть соотв. вр. файл

{fclose (ftmp);;

}((! strcmp (pole[0], «assume»))||(! strcmp (pole[0], "\0»)))

continue; //if пустое поле-чтение сл. строки=findop (pole[0]);(num) //if мнемокод операции - запись

{lent=op2code (num, 0, pole, cod); // объектн. кода во вр. файл

if (lent) {printf («code:»);(i=0; i<lent; i++)

{printf («%x», cod[i]);(cod[i], ftmp);

}+=lent;(«\n»);

}printf («Error: wrong operand!\n»);;

}=findop (pole[1]);(num) //if мнемокод операции - запись

{lent=op2code (num, 1, pole, cod); // объектн. кода во вр. файл(lent) {printf («code:»);(i=0; i<lent; i++)

{printf («%x», cod[i]);(cod[i], ftmp);

}+=lent;(«\n»);

}printf («Error: wrong operand!\n»);

} // во всех др. случаях - ошибка

}

/////////////////////creation object file\\\\\\\\\\\\\\\\\\\\\\\\\\* fobj; // создание объектн. файлаfnobj[]={«myprim.obj»};=fopen (fnobj, «w+b»);(fobj, «%c % c % c % c % s % c», 0x80,0xc, 0x0,0xa, «myprim.asm», 0x5d);

// название исходного ассемблерного файла(fobj, «%c % c % c % c % c % c % s % c», 0x88,0x20,0x0,0x0,0x0,0x1c,

«Turbo Assembler Version 3.2», 0x99); // версия ассемблера(fobj, «%c % c % c % c % c % c % c % c % c % c % s % c», 0x88,0x12,0x0,0x40,0xe9,

xb5,0x6e, 0xb0,0x30,0xa, «myprim.asm», 0x23);

// дополнительная запись с названием исходного ассемблерного файла

fprintf (fobj, «%c % c % c % c % c % c % c % c % c % c % c % c % c % c % c % c % c», 0x88,0x3,

x0,0x40,0xe9,0x4c, 0x96,0x2,0x0,0x0,0x68,0x88,0x3,0x0,0x40,

0xa1,0x94); // три постоянных записи(char y=0; y<=1; y++) // Две записи описания сегментов

{=0;=0x96; c+=i; putc (i, fobj);=strlen (segtab[y].name)+2; c+=i; putc (i, fobj);=0; c+=i; putc (i, fobj);=strlen (segtab[y].name); c+=i; putc (i, fobj);(char x=0; x<strlen (segtab[0].name); x++)

{i=toupper (segtab[y].name[x]); c+=i;(i, fobj);

}=0-c; putc (i, fobj);=0;=0x98; c+=i; putc (i, fobj);=0x7; c+=i; putc (i, fobj);=0x0; c+=i; putc (i, fobj);=0x60; c+=i; putc (i, fobj);=segtab[y].len; c+=i; putc (i, fobj);=0x0; c+=i; putc (i, fobj);=y+2; c+=i; putc (i, fobj);=0x1; c+=i; putc (i, fobj);=0x1; c+=i; putc (i, fobj);=0-c; putc (i, fobj);

}(fobj, «%c % c % c % c % c % c % c», 0x88,0x4,0x0,0x40,0xa2,0x1,0x91);

// запись начала сегментов (предсегментная запись)(y=0; y<=1; y++) // запись - тело сегментов

{=0;=0xa0; c+=i; putc (i, fobj);=segtab[y].len+4; c+=i; putc (i, fobj);=0; c+=i; putc (i, fobj);=y+1; c+=i; putc (i, fobj);=0; c+=i; putc (i, fobj);=0; c+=i; putc (i, fobj);=fopen (fname[y], «rb»);(char x=0; x<segtab[y].len; x++)

{i=getc(ftmp); c+=i;(i, fobj);

}(ftmp);=0-c; putc (i, fobj);

}[pmdf]='\0'; // запись - таблица ссылок(модификаторов)

c=0;=0x9c; c+=i; putc (i, fobj);=2*strlen(modif)+1; c+=i; putc (i, fobj);=0; c+=i; putc (i, fobj);=0xc8; c+=i; putc (i, fobj);=modif[0]; c+=i; putc (i, fobj);=0x54; c+=i; putc (i, fobj);=modif[1]; c+=i; putc (i, fobj);(y=2; y<strlen(modif); y+=2)

{i=0xc4; c+=i; putc (i, fobj);=modif[y]; c+=i; putc (i, fobj);=0x54; c+=i; putc (i, fobj);=modif [y+1]; c+=i; putc (i, fobj);

}=0-c; putc (i, fobj);(fobj, «%c % c % c % c % c % c % c % c % c % c», 0x8a, 0x7,0x0,

xc1,0x0,0x2,0x2,0x0,0x0,0xaa);

// запись - конец объектного файла

/////////////////////system information\\\\\\\\\\\\\\\\\\\\\\\\\\();();(» SYMTAB\n»); // вывод на экран таблиц:

printf (» name disp seg \n»); //SYMTAB, SEGTAB и табл. ссылок(i=0; i<psym; i++)(«%s %d %d \n»,[i].name, symtab[i].dsp, symtab[i].sgm);(«\n»);(» SEGTAB\n»);(» name N lent \n»);(i=0; i<2; i++)(«%s %d %d \n»,[i].name, i, segtab[i].len);(«\n»);

//printf («modifikatory \n»);

//for (i=0; i<pmdf; i++) printf («%x», modif[i]);(«\n»);(ft);(fobj);

getch();(0); // выход из транслятора.

}stk2pol (char st[80], char pol[4] [8]) // разбиение строки на поля

{fl=0, k=0, j=0; // внутр. перем.-счетчики и флаги=0;((st[i]!='\0')&&(st[i]!='\n')) // повторять пока не конец строки

{if ((st[i]==' ')||(st[i]==', ')||(st[i]==' ')||(j==8))

{if (fl) //if разделитель - переход на

{pol[k] [j]='\0'; // заполн. следующего поля

j=0;++;(k==4) return; //max кол-во полей = 4=0;

}

}if (st[i]==';') {for (; k<=3; k++) pol[k] [0]='\0';

return; //if комментарий - поля нулевые

}{fl=1; // запись символа в текущее поле

pol[k] [j]=st[i];++;

}++;

}[k] [j]='\0';++;(; k<=3; k++) pol[k] [0]='\0';; // конец stk2pol

}findop (char op[8]) // поиск мнемокода в OPTAB

{for (i=0; i<=7; i++) if (! strcmp (optab[i], op)) return (i+1);(0);}findsym (char sym[8]) // поиск метки в SYMTAB

{for (i=0; i<=psym; i++) if (! strcmp (symtab[i].name, sym)) return(i);(-1);

}findreg (char reg[8]) // поиск обознач. регистра в REGTAB

{for (i=0; i<=7; i++) if (! strcmp (regtab[i], reg)) return(i);(-1);

}findsegr (char reg[8]) // поиск обознач. сег. регистра в SEGRTAB

{for (i=0; i<=3; i++) if (! strcmp (segrtab[i], reg)) return(i);(-1);

}op2code (char nmb, char dis, char pol[4] [8], char code[4])

// ф-ция обработки команд ассемблера и директив

{struct bits // структура для доступа к

{char b0:1; char b1:1; char b2:1; char b3:1; // к отдельным битам.

char b4:1; char b5:1; char b6:1; char b7:1;

};bytes

{char c;b;

} temp, bcode;int2ch

{char c[2];d;

} tmp2;regn, regn2, segrn, tmp3; //regn, regn2, segrn-номера регистров

dis++;(nmb) // переход на обработчик соотв. команды

// MOV

{case 1: regn=findreg (pol[dis]);=findreg (pol[dis+1]);=findsegr (pol[dis]);

// непосредственная адресация((! regn)&&(! strcmp (segtab[0].name, pol [dis+1])))

{code[0]=0xb8; code[1]=0; code[2]=0; // код операции(npr) {modif[pmdf]=(cnt+3) - 2;++;[pmdf]=1;++;

}(3); // обраб. возвращ. длинну команды

}

// регистр в сегментный регистр((segrn!=-1)&&(regn2!=-1))

{code[0]=0x8e; // код операции.c=0xc0;.c=segrn;.b.b3=temp.b.b0; // номер сегментного регистра

bcode.b.b4=temp.b.b1;.c=regn2;.b.b0=temp.b.b0; // номер регистра.b.b1=temp.b.b1;.b.b2=temp.b.b2;[1]=bcode.c;

return(2); // обраб. возвращ. длинну команды

}((regn!=-1)||(regn2!=-1))

// Память в/из регистр AX (AL)

{if ((! regn)||(! regn2))

{bcode.c=0xa1; // код операции

if (regn) {bcode.b.b1=1; regn=regn2;}dis++;[0]=bcode.c;(npr)

{tmp3=findsym (pole[dis]);(tmp3==-1) return(0);{tmp2.d=symtab[tmp3].dsp;[1]=tmp2.c[0];[2]=tmp2.c[1];

}[pmdf]=(cnt+3) - 2;++;[pmdf]=symtab[tmp3].sgm;++;

}{code[1]=0; code[2]=0;}(3); // обраб. возвращ. длинну команды

}

// Регистр/память в/из регистр

{bcode.c=0x8b; // код операции

if (regn==-1) {bcode.b.b1=0; regn=regn2;}dis++;[0]=bcode.c;.c=0x06;.c=regn;

bcode.b.b3=temp.b.b0; // номер регистра -> код операции

bcode.b.b4=temp.b.b1;.b.b5=temp.b.b2;[1]=bcode.c;(npr)

{tmp3=findsym (pole[dis]);(tmp3==-1) return(0);{tmp2.d=symtab[tmp3].dsp;[2]=tmp2.c[0];[3]=tmp2.c[1];

}[pmdf]=(cnt+4) - 2;++;[pmdf]=symtab[tmp3].sgm;++;

}{code[2]=0; code[3]=0;}(4); // обраб. возвращ. длинну команды

}

};

//NEG2: regn=findreg (pol[dis]); (regn!=-1)

{code[0]=0xf7; // код операции

bcode.c=0xd8;.c=regn;

bcode.b.b0=temp.b.b0; // номер регистра -> код операции

bcode.b.b1=temp.b.b1;.b.b2=temp.b.b2;[1]=bcode.c;(2);

};

//JE3: if (npr)

{tmp3=findsym (pole[dis]);(tmp3==-1) return(0);code[1]=symtab[tmp3].dsp - (cnt+2); // определ. смешения

}code[1]=0;[0]=0x74; // код операции(2);;

//INC4: regn=findreg (pol[dis]);(regn!=-1)

{bcode.c=0x40; // код операции.c=regn;.b.b0=temp.b.b0; // номер регистра -> код операции.b.b1=temp.b.b1;.b.b2=temp.b.b2;[0]=bcode.c;

return(1); // обраб. возвращ. длинну команды

};

//SHL5: regn=findreg (pol[dis]);((regn!=-1)&&(! strcmp (pol[dis+1], «1»)))

{code[0]=0xd1; // код операции.c=0xe0;.c=regn;.b.b0=temp.b.b0; // номер регистра -> код операции.b.b1=temp.b.b1;.b.b2=temp.b.b2;[1]=bcode.c;

return(2); // обраб. возвращ. длинну команды

};

//ADC6: regn=findreg (pol[dis]);

if (regn!=-1)

{code[0]=0x13; // код операции

bcode.c=0xc0;.c=regn;

bcode.b.b3=temp.b.b0; // номер регистра -> код операции

bcode.b.b4=temp.b.b1;.b.b5=temp.b.b2;=findreg (pol[dis+1]);(regn!=-1)

{temp.c=regn;.b.b0=temp.b.b0; // номер регистра -> код операции.b.b1=temp.b.b1;.b.b2=temp.b.b2;[1]=bcode.c;

return(2); // обраб. возвращ. длинну команды

}

};

//INT7: code[0]=0xcd; // код операции[1]=str2num (pol[dis]);(code[1]!=-1) return(2);;

//DW8: tmp2.d=str2num (pol[dis]);[0]=tmp2.c[0];[1]=tmp2.c[1];(tmp2.d!=-1) return(2);;

}(0); //if ошибка - длинна ноль

}str2num (char str[8]) // перевод строки в соотв. число

{int zn, j;=0;=0;(str [strlen(str) - 1]=='h') // шестнадцатеричное число

for (char k=strlen(str) - 2; k>=0; k-)

{if (findch (str[k])==-1) return(-1); // не правильный формат - ошибка

zn=zn+(findch (str[k]))*step (16, j);++;

}// десятичное число

{for (char k=strlen(str) - 1; k>=0; k-)

{if (findch (str[k])==-1) return(-1);=zn+(findch (str[k]))*step (10, j);++;

}

}(zn);

}findch (char c) // поиск символа в HEXTAB

{for (i=0; i<=15; i++) if (hextab[i]==c) return(i);(-1);

}

step (int a, int b) // возведение A в степень B

{int z=1;(i=0; i<b; i++) z=z*a; return(z).

 


Список литературы

 

1. Абель П. Ассемблер и программирование для IBM PC. Технологический институт Британская Колумбия.

2. Журден Р. Справочник программиста на персональном компьютере фирмы IBM.

. Зубков С.В. Assembler для DOS, Windows и Unix. - М.: ДМК Пресс, 2000. - 608 с.: ил. (Серия для программистов).



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2020-04-01 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: