Проектирование компилятора
Контрольная работа - Компьютеры, программирование
Другие контрольные работы по предмету Компьютеры, программирование
В таблице мнемокодов отыскивается данный мнемокод и определяется индекс обработчика. Если мнемокод в таблице отсутствует, то генерируется ошибка. После того, как индекс получен, обработка строки передаётся соответствующему обработчику. На данном проходе обработчик определяет формат команды (в частности её длину) и соответствующим образом изменяет счётчик размещения.
К началу второго прохода адреса всех символических имён известны. Во время второго прохода окончательно генерируются объектные коды команд. Если в команде используется символическое имя, то оно отыскивается в таблице символических имён, и в соответствующее поле объектного кода записывается нужное значение (это может быть адрес символического имени или смещение до данного имени в зависимости от используемой команды). Объектный код записывается в вспомогательные файлы. Кроме того, если объектный код содержит поле, нуждающееся в модификации, то в таблицу vmodif записывается запись-модификатор.
Составление объектного файла.
По окончании второго прохода имеется вся необходимая информация для того, чтобы составить объектный файл. Записи, являющиеся неизменными для всех объектных файлов, записываются в виде констант. Остальные записи формируются на основании тех данных, которые были получены в результате первых двух проходов.
4. Исходный текст программы компилятора
#include;
#include;
#include;
#include;
#include;
#include;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); // версия ассембле