Проектирование компилятора

Принцип работы транслятора. Исследование формата данных объектного файла шестнадцатиразрядной системы DOS для последующего преобразования его в файл программы. Используемые директивы и команды ассемблера. Алгоритмы программы и таблицы компилятора.

Рубрика Программирование, компьютеры и кибернетика
Вид контрольная работа
Язык русский
Дата добавления 07.07.2012
Размер файла 35,9 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Цель работы

Изучить и понять принцип работы транслятора. Исследовать формат данных объектного файла для шестнадцатиразрядной системы DOS для последующего преобразования его в файл программы.

Расчет варианта задания производится по формуле:

компилятор программа ассемблер алгоритм

где NG - последние две цифры учебной группы; NS - номер студента в списке; KV - количество вариантов в соответствующей группе команд.

Получили следующие команды: NEG, JE, ADC, SHL, INC.

Задание: Для заданного набора команд разработать, отладить и протестировать программу - компилятор.

1. Разработка контрольного примера

Myprim.asm является программой для нахождения разницы между двумя большими числами (32 разряда). Использует все заданные команды

ADC, JE, NEG, SHL, INC и кроме того команды MOV, INT.

datas segment; сегмент данных

a1 dw 1001h; a1, a2, b1, b2 - исходные данные

a2 dw 10h; с1, с2 - результат

b1 dw 0abcdh

b2 dw 20h

c1 dw 0

c2 dw 0

vix dw 4c00h; 4ch - ф-ция выхода, 00h - код возврата

datas ends

codes segment

start:

assume cs:codes, ds:datas

mov ax, datas

mov ds, ax

mov ax, a1;

mov dx, a2; загрузить данные в

mov bx, b1; регистры

mov cx, b2;

neg ax;

je m1;

inc dx; инверсия первого числа

m1: neg dx;

mov di, c1; 0 -> бит CF

shl di, 1;

adc ax, bx; сложить младшие части

adc dx, cx; сложить старшие части и бит CF

je m2

mov c1, ax; сохранить

m2: mov c2, dx; результат

mov ax, vix; завершение

int 21h; программы

codes ends

end start

Находится разница между двумя 32-разрядными операндами. Второй операнд инвертируется и складывается с первым. Операнды и результат располагаются в памяти. Базовый набор команд дополнен командами: MOV и INT, директивой - DW.

Данный контрольный пример без ошибок компилируется и линкуется стандартными компиляторами и линковщиками.

2. Описание используемых директив и команд ассемблера

ADC: Сложение с переносом

Операция: Обычно используется при сложении многословных величин для учета бита переполнения в последующих фазах операции. Если флаг CF установлен в 1, то команда ADC сначала прибавляет 1 к операнду 1. Команда всегда прибавляет операнд 2 к операнду 1, аналогично команде ADD.

Флаги: Команда воздействует на флаги AF, CF, OF, PF, SF и ZF.

Объектный код (три формата): Регистр плюс регистр или память:|000100dw|modregr/m|.

INT: Прерывание

Операция: Прерывает выполнение программы и передает управление по одному из 256 адресов (векторов прерывания). Команда INT выполняет следующее: 1) уменьшает значение SP на 2 и заносит в стек флаговый регистр, сбрасывает флаги IF и TF; 2) уменьшает значение SP на 2 и заносит регистр CS в стек, старшее слово из вектора прерывания помещает в регистр CS; 3) уменьшает значение SP на 2 и заносит регистр IP в стек, младшее слово из вектора прерывания помещает в регистр IP.

Флаги: Команда воздействует на флаги IF и TF.

Объектный код: |1100110v|-type-| (если v = 0, то type = 3).

INT const: Прерывание

Операция: Прерывает выполнение программы и передаёт управление по одному из 256 адресов (векторов прерывания).

Объектный код: |11001101|-type-|.

JE/JZ: Переход по «равно» или по «нулю»

Операция: Используется после проверки знаковых или беззнаковых данных для передачи управления по другому адресу. Если флаг ZF равен единице (нулевое состояние), то команда прибавляет к регистру IP значение операнда (относительное смещение) и выполняет таким образом переход.

Флаги: Не меняются.

Объектный код: |01110100|-disp-|

MOV: Пересылка данных

Операция: Пересылает один байт или одно слово между регистрами или между регистром и памятью, а также передает непосредственное значение в регистр или в память. Команда MOV не может передавать данные между двумя адресами памяти (для этой цели служит команда MOVS). Существует семь типов команды MOV.

Флаги: Не меняются.

Объектный код (семь форматов):

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

|100010dw|modregr/m|

Непосредственное значение в регистр:

|1011wreg|-data-|data если w=1|

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

|1010000w|addr-low|addr-high|

Регистр AX (AL) в память:

|1010001w|addr-low|addr-high|

Регистр/память в сегментный регистр:

|10001110|mod0sgr/m| (sg - сегментный регистр)

NEG: Изменение знака числа

Операция: Меняет двоичное значение из положительного в отрицательное и из отрицательного в положительное. Команда NEG вычисляет двоичное дополнение от указанного операнда: вычитает операнд из нуля и прибавляет единицу. Операндом может быть байт или слово в регистре или в памяти.

Флаги: Команда воздействует на флаги AF, CF, OF, PF, SF и ZF.

Объектный код: |1111011w|mod011r/m|

SHL: Сдвиг влево или вправо

Операция: Выполняет сдвиг битов влево.

Флаги: Команда воздействует на флаги CF, OF, PF, SF и ZF (флаг AF не определен).

Объектный код: SAL/SHL: |110100cw|mod100r/m|.

3. Алгоритмы и таблицы компилятора

Компилятор, разрабатываемый в данной курсовой, является двух-проходным. Он использует следующие системные таблицы.

OPTAB - таблица мнемокодов. Содержит следующие поля: name - мнемокод. SYMTAB - таблица символических имён. Содержит следующие поля: name - символическое имя; sgm - сегмент, в котором оно объявлено; dsp - смещение в сегменте. SEGTAB - таблица сегментов. Содержит следующие поля: name - имя сегмента; len - длина сегмента в байтах.

Кроме выше перечисленных таблиц, используются два временных файла предназначенных для хранения объектного код двух сегментов. Также используется таблица modif используемых ссылок (записи модификаторы).

На первом проходе происходит заполнение таблицы символических имён и таблицы используемых сегментов. Кроме того, определяются форматы команд, без чего невозможно заполнение системных таблиц. Мнемокоды обрабатываются следующим образом. Вся строка разбивается на поля. Если в строке имеется символическое имя, то оно заносится в таблицу. Далее определяется поле с мнемокодом. В таблице мнемокодов отыскивается данный мнемокод и определяется индекс обработчика. Если мнемокод в таблице отсутствует, то генерируется ошибка. После того, как индекс получен, обработка строки передаётся соответствующему обработчику. На данном проходе обработчик определяет формат команды (в частности её длину) и соответствующим образом изменяет счётчик размещения.

К началу второго прохода адреса всех символических имён известны. Во время второго прохода окончательно генерируются объектные коды команд. Если в команде используется символическое имя, то оно отыскивается в таблице символических имён, и в соответствующее поле объектного кода записывается нужное значение (это может быть адрес символического имени или смещение до данного имени в зависимости от используемой команды). Объектный код записывается в вспомогательные файлы. Кроме того, если объектный код содержит поле, нуждающееся в модификации, то в таблицу vmodif записывается запись-модификатор.

Составление объектного файла.

По окончании второго прохода имеется вся необходимая информация для того, чтобы составить объектный файл. Записи, являющиеся неизменными для всех объектных файлов, записываются в виде констант. Остальные записи формируются на основании тех данных, которые были получены в результате первых двух проходов.

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

#include<stdio.h>;

#include<string.h>;

#include<stdlib.h>;

#include<ctype.h>;

#include<conio.h>;

#include<io.h>;

char i, c, npr, seg, cnt, pmdf, psym, stk[80], pole[4] [8];

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

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

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

 // считанной строки.

char optab[8] [4]={{«mov»}, {«neg»}, {«je\0»}, {«inc»}, // таблица

{«shl»}, {«adc»}, {«int»}, {«dw\0»}}, // мнемокодов

regtab[8] [3]={{«ax»}, {«cx»}, {«dx»}, {«bx»}, // таблицы обозначений

{«sp»}, {«bp»}, {«si»}, {«di»}}, // регистров и

segrtab[4] [3]={{«es»}, {«cs»}, {«ss»}, {«ds»}}, // сегментных регистров

hextab[17]={«0123456789abcdef»},

modif[20]; // таблица модификаторов

struct segt {

char name[8];

char len;

};

segt segtab[2]; // таблица сегментов

struct symt {

char name[8];

char sgm;

int dsp;

};

symt symtab[10]; // таблица меток

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

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

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

 // на входе мнемокод, на выходе длинна команды и объектный код

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

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

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

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

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

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

int main()

{

char cod[4], lent, // код и длинна команды

num; // номер обработчика команды

FILE * ft; // исходный ассемблерный файл

char fn[]={«myprim.asm»};

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

clrscr();

 ////////////////////////////first passage\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

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

seg=0;

npr=0;

psym=0;

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

{fgets (stk, 80, ft); // чтение строки

printf («\n»);

getch();

puts(stk);

stk2pol (stk, pole); // разбиение строки на поля

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

{seg++; // увеличение номера сегмента, запись

cnt=0; // названия в SEGTAB, сброс счетчика

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

continue;

}

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

{segtab [seg-1].len=cnt;

printf («add to segtab:%s % d % d\n»,

segtab [seg-1].name, seg, segtab [seg-1].len);

continue;

}

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

continue; //if пустое поле-чтение сл. строки

num=findop (pole[0]);

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

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

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

cnt+=lent;

}

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

continue;

}

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

{if (pole[0] [strlen (pole[0]) - 1]==':')

pole[0] [strlen (pole[0]) - 1]='\0'; //if метка

if (findsym (pole[0])==-1) // не найдена в SYMTAB

{strcpy (symtab[psym].name, pole[0]); // занесение в SYMTAB

symtab[psym].sgm=seg;

symtab[psym].dsp=cnt;

printf («add to symtab:%s % d % d\n»,

symtab[psym].name, symtab[psym].sgm, symtab[psym].dsp);

psym++;

} //if метка найдена - ошибка

else printf («Error: label % s retry!\n», pole[0]);

if (! strcmp(pole[1], "\0»)) continue;

num=findop (pole[1]);

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

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

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

cnt+=lent;

}

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

}

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

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

}

 ////////////////////////////second passage\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

FILE * ftmp; // временные файлы

char fname[2] [10]={{«temp1.dat»}, {«temp2.dat»}};

getch();

clrscr();

printf (» *** second passage *** \n»);

pmdf=0;

npr++;

seg=0;

rewind(ft);

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

{fgets (stk, 80, ft); // чтение строки

printf («\n»);

getch();

puts(stk);

stk2pol (stk, pole); // разбиение строки на поля

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

{seg++; // увеличение номера сегмента

ftmp=fopen (fname [seg-1], «w+b»); // открыть соотв. вр. файл

cnt=0; // сброс счетчика размещения

continue;

}

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

{fclose (ftmp);

continue;

}

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

continue; //if пустое поле-чтение сл. строки

num=findop (pole[0]);

if (num) //if мнемокод операции - запись

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

if (lent) {printf («code:»);

for (i=0; i<lent; i++)

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

putc (cod[i], ftmp);

}

cnt+=lent;

printf («\n»);

}

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

continue;

}

num=findop (pole[1]);

if (num) //if мнемокод операции - запись

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

if (lent) {printf («code:»);

for (i=0; i<lent; i++)

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

putc (cod[i], ftmp);

}

cnt+=lent;

printf («\n»);

}

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

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

}

 /////////////////////creation object file\\\\\\\\\\\\\\\\\\\\\\\\\\

FILE * fobj; // создание объектн. файла

char fnobj[]={«myprim.obj»};

fobj=fopen (fnobj, «w+b»);

fprintf (fobj, «%c % c % c % c % s % c», 0x80,0xc, 0x0,0xa, «myprim.asm», 0x5d);

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

fprintf (fobj, «%c % c % c % c % c % c % s % c», 0x88,0x20,0x0,0x0,0x0,0x1c,

«Turbo Assembler Version 3.2», 0x99); // версия ассемблера

fprintf (fobj, «%c % c % c % c % c % c % c % c % c % c % s % c», 0x88,0x12,0x0,0x40,0xe9,

0xb5,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,

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

0xa1,0x94); // три постоянных записи

for (char y=0; y<=1; y++) // Две записи описания сегментов

{

c=0;

i=0x96; c+=i; putc (i, fobj);

i=strlen (segtab[y].name)+2; c+=i; putc (i, fobj);

i=0; c+=i; putc (i, fobj);

i=strlen (segtab[y].name); c+=i; putc (i, fobj);

for (char x=0; x<strlen (segtab[0].name); x++)

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

putc (i, fobj);

}

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

c=0;

i=0x98; c+=i; putc (i, fobj);

i=0x7; c+=i; putc (i, fobj);

i=0x0; c+=i; putc (i, fobj);

i=0x60; c+=i; putc (i, fobj);

i=segtab[y].len; c+=i; putc (i, fobj);

i=0x0; c+=i; putc (i, fobj);

i=y+2; c+=i; putc (i, fobj);

i=0x1; c+=i; putc (i, fobj);

i=0x1; c+=i; putc (i, fobj);

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

}

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

 // запись начала сегментов (предсегментная запись)

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

{

c=0;

i=0xa0; c+=i; putc (i, fobj);

i=segtab[y].len+4; c+=i; putc (i, fobj);

i=0; c+=i; putc (i, fobj);

i=y+1; c+=i; putc (i, fobj);

i=0; c+=i; putc (i, fobj);

i=0; c+=i; putc (i, fobj);

ftmp=fopen (fname[y], «rb»);

for (char x=0; x<segtab[y].len; x++)

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

putc (i, fobj);

}

fclose (ftmp);

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

}

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

c=0;

i=0x9c; c+=i; putc (i, fobj);

i=2*strlen(modif)+1; c+=i; putc (i, fobj);

i=0; c+=i; putc (i, fobj);

i=0xc8; c+=i; putc (i, fobj);

i=modif[0]; c+=i; putc (i, fobj);

i=0x54; c+=i; putc (i, fobj);

i=modif[1]; c+=i; putc (i, fobj);

for (y=2; y<strlen(modif); y+=2)

{i=0xc4; c+=i; putc (i, fobj);

i=modif[y]; c+=i; putc (i, fobj);

i=0x54; c+=i; putc (i, fobj);

i=modif [y+1]; c+=i; putc (i, fobj);

}

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

fprintf (fobj, «%c % c % c % c % c % c % c % c % c % c», 0x8a, 0x7,0x0,

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

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

 /////////////////////system information\\\\\\\\\\\\\\\\\\\\\\\\\\

getch();

clrscr();

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

printf (» name disp seg \n»); //SYMTAB, SEGTAB и табл. ссылок

for (i=0; i<psym; i++)

printf («%s %d %d \n»,

symtab[i].name, symtab[i].dsp, symtab[i].sgm);

printf («\n»);

printf (» SEGTAB\n»);

printf (» name N lent \n»);

for (i=0; i<2; i++)

printf («%s %d %d \n»,

segtab[i].name, i, segtab[i].len);

printf («\n»);

 //printf («modifikatory \n»);

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

printf («\n»);

fclose (ft);

fclose (fobj);

getch();

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

}

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

{

char fl=0, k=0, j=0; // внутр. перем.-счетчики и флаги

i=0;

while ((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++;

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

fl=0;

}

}

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

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

}

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

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

j++;

}

i++;

}

pol[k] [j]='\0';

k++;

for (; k<=3; k++) pol[k] [0]='\0';

return; // конец stk2pol

}

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

{for (i=0; i<=7; i++) if (! strcmp (optab[i], op)) return (i+1);

return(0);}

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

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

return(-1);

}

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

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

return(-1);

}

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

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

return(-1);

}

char 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;

};

union bytes

{char c;

bits b;

} temp, bcode;

union int2ch

{char c[2];

int d;

} tmp2;

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

dis++;

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

 // MOV

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

regn2=findreg (pol[dis+1]);

segrn=findsegr (pol[dis]);

 // непосредственная адресация

if((! regn)&&(! strcmp (segtab[0].name, pol [dis+1])))

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

if (npr) {modif[pmdf]=(cnt+3) - 2;

pmdf++;

modif[pmdf]=1;

pmdf++;

}

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

}

 // регистр в сегментный регистр

if((segrn!=-1)&&(regn2!=-1))

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

bcode.c=0xc0;

temp.c=segrn;

bcode.b.b3=temp.b.b0; // номер сегментного регистра

bcode.b.b4=temp.b.b1;

temp.c=regn2;

bcode.b.b0=temp.b.b0; // номер регистра

bcode.b.b1=temp.b.b1;

bcode.b.b2=temp.b.b2;

code[1]=bcode.c;

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

}

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

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

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

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

if (regn) {bcode.b.b1=1; regn=regn2;}

else dis++;

code[0]=bcode.c;

if (npr)

{tmp3=findsym (pole[dis]);

if (tmp3==-1) return(0);

else {tmp2.d=symtab[tmp3].dsp;

code[1]=tmp2.c[0];

code[2]=tmp2.c[1];

}

modif[pmdf]=(cnt+3) - 2;

pmdf++;

modif[pmdf]=symtab[tmp3].sgm;

pmdf++;

}

else {code[1]=0; code[2]=0;}

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

}

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

else

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

if (regn==-1) {bcode.b.b1=0; regn=regn2;}

else dis++;

code[0]=bcode.c;

bcode.c=0x06;

temp.c=regn;

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

bcode.b.b4=temp.b.b1;

bcode.b.b5=temp.b.b2;

code[1]=bcode.c;

if (npr)

{tmp3=findsym (pole[dis]);

if (tmp3==-1) return(0);

else {tmp2.d=symtab[tmp3].dsp;

code[2]=tmp2.c[0];

code[3]=tmp2.c[1];

}

modif[pmdf]=(cnt+4) - 2;

pmdf++;

modif[pmdf]=symtab[tmp3].sgm;

pmdf++;

}

else {code[2]=0; code[3]=0;}

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

}

}

break;

 //NEG

case 2: regn=findreg (pol[dis]);

if (regn!=-1)

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

bcode.c=0xd8;

temp.c=regn;

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

bcode.b.b1=temp.b.b1;

bcode.b.b2=temp.b.b2;

code[1]=bcode.c;

return(2);

}

break;

 //JE

case 3: if (npr)

{tmp3=findsym (pole[dis]);

if (tmp3==-1) return(0);

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

}

else code[1]=0;

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

return(2);

break;

 //INC

case 4: regn=findreg (pol[dis]);

if (regn!=-1)

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

temp.c=regn;

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

bcode.b.b1=temp.b.b1;

bcode.b.b2=temp.b.b2;

code[0]=bcode.c;

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

}

break;

 //SHL

case 5: regn=findreg (pol[dis]);

if ((regn!=-1)&&(! strcmp (pol[dis+1], «1»)))

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

bcode.c=0xe0;

temp.c=regn;

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

bcode.b.b1=temp.b.b1;

bcode.b.b2=temp.b.b2;

code[1]=bcode.c;

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

}

break;

 //ADC

case 6: regn=findreg (pol[dis]);

if (regn!=-1)

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

bcode.c=0xc0;

temp.c=regn;

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

bcode.b.b4=temp.b.b1;

bcode.b.b5=temp.b.b2;

regn=findreg (pol[dis+1]);

if (regn!=-1)

{temp.c=regn;

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

bcode.b.b1=temp.b.b1;

bcode.b.b2=temp.b.b2;

code[1]=bcode.c;

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

}

}

break;

 //INT

case 7: code[0]=0xcd; // код операции

code[1]=str2num (pol[dis]);

if (code[1]!=-1) return(2);

break;

 //DW

case 8: tmp2.d=str2num (pol[dis]);

code[0]=tmp2.c[0];

code[1]=tmp2.c[1];

if (tmp2.d!=-1) return(2);

break;

}

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

}

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

{int zn, j;

zn=0;

j=0;

if (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);

j++;

}

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

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

{if (findch (str[k])==-1) return(-1);

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

j++;

}

}

return(zn);

}

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

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

return(-1);

}

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

{int z=1;

for (i=0; i<b; i++) z=z*a; return(z).

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

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

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

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

Размещено на Allbest.ru


Подобные документы

  • Взаимосвязь стадий процесса проектирования сложных программных систем. Создание компилятора подмножества языка высокого уровня (Pascal) на язык Ассемблера. Структура входных и выходных данных, алгоритмы их обработки. Рабочая документация программы.

    курсовая работа [256,7 K], добавлен 27.07.2014

  • Задачи трансляторов, характеристика их видов. Этапы и функции основных фаз процесса компиляции. Описание используемых директив и команд ассемблера, алгоритмов, таблиц. Листинг программы. Алгоритм работы программной реализации разрабатываемого компилятора.

    курсовая работа [1,3 M], добавлен 24.06.2013

  • Функции компилятора как системной обрабатывающей программы. Этапы компиляции: анализ и синтез. Разработка лексического анализатора. Алгоритм и программа лексического анализа. Реализация двухфазного компилятора. Описание логической структуры программы.

    курсовая работа [310,4 K], добавлен 26.03.2010

  • Разработка транслятора упрощенного языка ассемблера. Преобразование файла в мнемокодах в файл, содержащий объектный двоичный код. Анализ набора команд. Выбор формата ассемблерной команды. Методика определения типа операнда. Формирование строки листинга.

    курсовая работа [189,2 K], добавлен 14.02.2016

  • Описание работы программы, осуществляющей запись команд графического экрана в файл формата BMP. Изучение функции чтения 18-битовых значений из нескольких последовательно расположенных регистров таблицы цветов. Составление блок-схемы и текста программы.

    курсовая работа [198,1 K], добавлен 20.11.2012

  • Создание приложения к реляционной базе данных "Личная фонотека". Исследование предметной области, выбор языка программирования и компилятора. Проектирование функциональности, структура программы, использованные алгоритмы; взаимодействие с пользователем.

    курсовая работа [613,5 K], добавлен 29.12.2015

  • Построение компилятора с языка высокого уровня как одного из элементов системы программирования. Разработка компилятора ассемблера, модификация базы данных исходного макета. Загрузчик, эмулятор, отладчик. Использование Flex и Bison для программирования.

    курсовая работа [599,0 K], добавлен 04.11.2014

  • Основы проверки и расчета входных данных и вывода выходных данных программы, их блок-схемы. Реализация функции считывания числовых данных из файла, управление (создание, уничтожение и редактирование) визуальными компонентами во время выполнения программы.

    контрольная работа [1,3 M], добавлен 12.06.2009

  • Структура, классификация и требования к реализации компилятора. Проектирование и реализация анализирующей части компилятора языка С++. Способы реализации лексического анализа. Алгоритм работы синтаксического анализатора. Принципы программной реализации.

    курсовая работа [774,2 K], добавлен 26.01.2013

  • Реализация программы-конвертера для создания на основе передаваемых dbf файлов файла формата XML (по заданному пользователем шаблону). Создание шаблонов при помощи кода и при помощи конструктора. Проектирование архитектуры программного продукта.

    дипломная работа [1,6 M], добавлен 27.06.2013

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.