У вас вопросы?
У нас ответы:) SamZan.net

Задание Разработать на основе предикативного анализатора компилятор c языка программирования которы

Работа добавлена на сайт samzan.net: 2016-03-30

Поможем написать учебную работу

Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 11.4.2025

Омский государственный технический университет

Кафедра ИВТ

Курсовая работа

по дисциплине:

«Системное программное обеспечение»

Выполнил: Мусайбеков К.К.

гр. ИВТ-415

 

Проверил: Флоренсов А.Н.

Омск 2008


Задание

Разработать на основе предикативного анализатора компилятор c языка   программирования, который описательно задается следующими определениями

  1.  язык обеспечивает вычисления только в целых числах и допускает использование одномерных массивов;
  2.  для задания массивов используются описания вида:

    array имя_массива [ размерность_массива ];

где размерность_массива задаётся целым числом;

  1.  переменная определяется либо как идентификатор, либо как идентификатор, за которым в квадратных скобках записано обозначение переменной или константы (второй вариант называется индексированной переменной);
  2.  в левой части оператора присваивания может стоять обычная или индексированная переменная;
  3.  арифметические выражения могут состоять из скольки угодно операндов;
  4.  язык содержит операторы цикла, задаваемые ключевым словами repeat - until, for, while и условные операторы if  [ - else]; допускаются операторы continue, break;
  5.  условия задаются в виде

    выражение операция_сравнения выражение

для выдачи результатов служат операторы: 

  write выражение  [ , выражение, …]

для ввода оператор

 read  переменная  [ , переменная, …]

  1.  остальные синтаксические элементы языка выбираются разработчиком самостоятельно (скобки, средства указания конца оператора, блока операторов, символ присваивания, обозначения операций сравнения и т.п.);
  2.  Имена программных объектов должны формироваться по общеупотребительному правилу: первым символом должна быть произвольная латинская буква, последующими символами могут быть цифры или латинские буквы.

Основным результатом работы компилятора должен быть либо исполняемый файл, либо файл объектного кода - в зависимости от опции вызова этого компилятора;

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

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


Текст программы

Файл main.c

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <ctype.h>

#define IF             256                   //Определяем константы, используемые далее по ходу программы

#define ELSE           257

#define REPEAT         258

#define UNTIL          259

#define READ           260

#define WRITE          261

#define START          262

#define END            263

#define INT            264

#define ARRAY          265

#define ASSUME         266

#define IDENT          267

#define NUMBER         268

#define OPERATOR       269

#define OPENBRACKET    270

#define CLOSEBRACKET   271

#define DOTCOMMA       272

#define CONTINUE       273

#define OPENSQBRACKET  274

#define CLOSESQBRACKET 275

#define BREAK          276

#define COMMA          277

#define FOR            278

#define WHILE          279

#define WRITELN        280

#define PROCEDURE      281

#define HOSTWHILE      4

#define HOSTFOR        3

#define HOSTREPEAT     2

#define HOSTOTHER      1

#define ASMEND_IF      "%s_%ld:\n"           //Определяем асмовские конструкции

#define ASMIF_ELSE     " jmp %s_%ld\n%s_%ld:\n"                 //на базе которых будет строится программа

#define ASMSTATEMENT   " pop dword [%s+4*%ld]\n"

#define ASMSTATEMENT1  " mov edi, [%s+4*%ld]\n pop dword [%s+4*edi]\n"

#define ASMNEGATE      " pop eax\n neg eax\n push eax\n"

#define ASMASSUME_MEM  " push dword [%s+4*%ld]\n"

#define ASMASSUME_NUM  " push dword %ld\n"

#define ASMASSUME_MEM1 " mov edi,[%s+4*%ld]\n push dword [%s+4*edi]\n"

#define ASMCONDITION   " pop ebx\n pop eax\n cmp eax,ebx\n %s near %s_%ld\n"

#define ASMREPEAT      "repeat_%ld:\n"

#define ASMJMP         " jmp near %s_%ld\n"

#define ASMUNTIL       "until_%ld:\n"

#define ASMREAD        " call stdread\n mov [%s+4*%ld],eax\n"

#define ASMREAD1       " call stdread\n mov edi,[%s+4*%ld]\n mov [%s+4*edi],eax\n"

#define ASMLN          " call lfwrite\n"

#define ASMWRITE       " pop eax\n call itox\n"

#define ASMFOR         "for_%ld:\n"

#define ASMENDFOR      " jmp near for_%ld\nendfor_%ld:\n"

#define ASMWHILE       "while_%ld:\n"

#define ASMENDWHILE    " jmp while_%ld\nendwhile_%ld:\n"

#define ASMPROCSTART   "%s:\n push ebp\n mov ebp, esp\n"

#define ASMPROCEND     " mov esp,ebp\n pop ebp\n ret\n\n\n"

#define ASMCALL        " call %s\n"

#define ASMVARIABLE    " mov eax, [ebp + %ld]\n mov [%s], eax\n"

#define ASMVARIABLE1   " push dword %s\n"

char CodeHeader[]      = "EXTERN stdexit, stdread, itox, lfwrite\nsegment .text USE32 CLASS=CODE\n\n..start:\n call main\n call stdexit\n", //Заголовок кода

    DataHeader[]      = " segment .data USE32\n";              

char MathOpAsm[8][100] = {                                      

    " pop ebx\n pop eax\n add eax,ebx\n push eax\n",

    " pop ebx\n pop eax\n sub eax,ebx\n push eax\n",

    " pop ebx\n pop eax\n mul ebx\n push eax\n",

    " pop ebx\n pop eax\n xor edx,edx\n div ebx\n push eax\n",

    " pop ebx\n pop eax\n xor edx,edx\n div ebx\n push edx\n",

    " pop ebx\n mov eax,1\n add eax,ebx\n push eax\n",

    " pop eax\n mov ebx,1\n sub eax,ebx\n push eax\n",

    " pop eax\n mov ebx,eax\n mul ebx\n push eax\n"};

char OpMath[8][3]   = {"+", "-", "*", "/", "%", "++", "--", "**"},

    StrLogic[6][4] = {"je", "jl", "jle", "jg", "jge", "jne"},

    OpLogic[6][3]  = {"!=", ">=", ">",   "=<", "<",   "=="};

typedef struct {                           //В данной структуре будут храниться все токены и их значения

         int  token;

         char *value;

         int  line;

       } TOKEN;

typedef struct{                                                 //В данной структуре будут храниться все

         char *name;                                           //зарегестрированные переменные и процедуры

         int  size;

} datahold;

struct {                                                        //Здесь хранятся зарезервированые слова

  char name[32];

  int  type;

} KeywordList[23] = {

  {"if",       IF},

  {"else",     ELSE},

  {"repeat",   REPEAT},

  {"until",    UNTIL},

  {"read",     READ},

  {"write",    WRITE},

  {"{",        START},

  {"}",        END},

  {"int",      INT},

  {"array",    ARRAY},

  {"=",        ASSUME},

  {"(",        OPENBRACKET},

  {")",        CLOSEBRACKET},

  {";",        DOTCOMMA},

  {"continue", CONTINUE},

  {"[",        OPENSQBRACKET},

  {"]",        CLOSESQBRACKET},

  {"break",    BREAK},

  {",",        COMMA},

  {"for",      FOR},

  {"while",    WHILE},

  {"writeln",  WRITELN},

  {"procedure",PROCEDURE}

};

unsigned int   count     = 0;                          //Счетчик

FILE           *inpfile,                                        //Хэндл входного файла

              *outfile;                                        //Хэндл выходного файла

int            token     = 0,                                   //Текущий токен

              tokennum  = 0,                                   //Общее количество токенов

              curtoken  = 0,                                   //Номер текущий токен

              datanum   = 0,                                   //Общее количество зарегестрированных переменных

              procnum   = 0,                                   //Общее количество процедур

              ifcounter = 0,                                   //Количсетво ифоф

              rcounter  = 0,                                   //Количество репитов

              wcounter  = 0,                                   //Количество вайлов

              fcounter  = 0;                                   //Количество форов

char           ops[]     = {'+', '-', '*', '/', '<', '>', '^', '=', '!', '%', 0},    //Все операторы

              outname[128];                                    //Путь к файлу

TOKEN          *tarr     = 0;                                   //Указатель на массив с токенами

datahold       *data     = 0,                                   //Указатель на массив с зарегенными данными

              *proch    = 0;                                   //Указатель на массив с зареганными процедурами

long FileSize    (FILE *stream);                                //Описываем заголовки функций

int  ScanList    (char *buffer);

int  LexAnalyz   (char *buffer);

int  Logic       (void);

int  Condition   (char *id_str,int cnt);

int  GetOp       (void);

int  GetPar      (char **name,int *index,int *value, char **name1);

int  Expression  (void);

int  Factor      (void);

int  IdentCheck  (datahold *data, int datanum);

int  Index       (char **name1);

int  Variable    (char **name, int *index, char **name1);

int  Code        (int host, int count);

int  Statement   (int host, int count);

int  DataOut     (FILE *outfile);

int  Parse       (void);

int  RunNasmW    (void);

int  RunTlink32  (void);

int  OtherOut    (void);

int  RepeatUntil (int rcount);

int  IfElse      (int ifcount, int host, int count);

int  ForDo       (int forcounter);

int  WhileDo     (int rcount);

long FileSize(FILE *stream) {                             //Функция, опеределяющая размер файла

                                                               //Входной параметр: файловый дескриптор

   long curpos, length;

   curpos = ftell(stream);

   fseek(stream, 0L, SEEK_END);

   length = ftell(stream);

   fseek(stream, curpos, SEEK_SET);

   return length;

}

int ScanList (char *buffer) {                           //Функция, сканирующая массив с ключевыми словами

                                                              //и выдающая токен ключевого слова если он найден

   int i;                                                     //Входной параметр: идентификатор

   for (i = 0;i < 23; i++) {

       if (!strncmp(buffer, KeywordList[i].name, 32)) {

          return KeywordList[i].type;

       }

   }

   return -1;

}

int LexAnalyz(char *buffer) {                            //Лексический анализатор

                                                               //Входной параметр: входной поток символов

   int  i,                                                     //Счетчик

        line = 1;                                              //Счетчик линий в файле

   char *value,                                                //Указатель на ячейку данных

        error[50];                                             //Строка содержащая ошибку

   memset(error, 0, 50);

   while (count < strlen(buffer)) {                            //Перебираем все символы входного потока

      i = 0;

      if (buffer[count] == '\n') {                             //Если встретили перевод строки, тогда

         line++;                                               //увеличиваем номер строки и переходим к следующему

         count++;                                              //символу

         continue;

      }

      if (isdigit(buffer[count])) {                            //Если встретили цифру, тогда пытаемся выделить все число

          value = malloc(128);

          while (isdigit(buffer[count])) {

             value[i++] = buffer[count];

             if (i > 126) {

                strcpy(error, "Ошибка: при лексическом анализе - переполнение\n");

                break;

             }

             count++;

          }

          value[i] = 0;                                        //Последний символ равен 0

          token    = NUMBER;                                   //Токен - число

      } else {                                                 

         if (isalpha(buffer[count])) {                         //Если встретили символ, тогда выделяем весь идентификатор

             value = malloc(128);

             while (isalpha(buffer[count]) || isdigit(buffer[count])) {    //Последующие символы могут быть и цифрой

                value[i++] = buffer[count];

                if (i > 126) {

                   strcpy(error, "Ошибка: при лексическом анализе - переполнение\n");

                   break;

                }

                count++;

             }                                   

             value[i] = 0;                                     //Последний символ 0

             if ((i = ScanList(value)) == -1) {                //Проверяем, ключевое ли это слово

                token = IDENT;                                 //Токен - идентификатор

             } else {

                token = i;                                     //Токен - ключевое слово

             }

         } else {

            if (strchr(ops, buffer[count])) {                  //Если это операция, тогда выделяем ее

               value = malloc(128);

               while (strchr(ops, buffer[count])) {

                  value[i++] = buffer[count];

                  if (i > 126) {

                     strcpy(error, "Ошибка: при лексическом анализе - переполнение\n");

                     break;

                  }

                  count++;

               }

               value[i] = 0;

               if ((i = ScanList(value)) == -1) {              //Не знак ли это равенства?

                  token = OPERATOR;                            //Токен - оператор

                 } else {

                  token = i;                                   //Токен - знак равенства

               }

            } else {                                           //Проверяем, не скобки ли это {} или не ; или не [] или не ,

               value    = malloc(2);                           //или не ()

               value[0] = buffer[count];

               value[1] = 0;

               if ((i = ScanList(value)) == -1) {              //Если нет, то продолжаем далее, иначе токен - ключевое слово

                  count ++;

                  continue;

               } else {

                  token = i;

                  count++;

               }

            }

         }

      }                                                        //Конец while

      tarr = realloc(tarr, (tokennum + 2) * sizeof(TOKEN));    //Выделяем память, чтобы записать очередной токен

      tarr[tokennum].value = value;

      tarr[tokennum].token = token;               

      tarr[tokennum].line  = line;

      tokennum++;

   }

   if (strlen(error) == 0) {                                   //Если ошибок нет, то завершаем работу анализатора

      printf("Лексческий анализ успешно выполнен\n");

      return 0;

   } else {

      printf(error);

      return -1;

   }

}

int Logic() {                                                   //Функция, идентифицирующая текущую логическую операцию

   int i,                                                      //Счетчик

       retv = -1;                                              //Возвращаемое значение

   if (strlen(tarr[curtoken].value) > 2) {                 

      printf("Ошибка %d: Неверная логическая операция %s\n", tarr[curtoken].line, tarr[curtoken].value);

      return -1;

   }

   for (i=0; i < 6; i++) {                                 //Ищем текущую операцию в массиве операций

       if (!strcmp(tarr[curtoken].value, OpLogic[i])) {        //Если нашли, то заканчиваем работу и возвращаем номер

          retv = i;                                            //этой операции в нашем массиве

          break;

       }

   }

   curtoken++;

   if (retv == -1) {

      printf("Ошибка %d: Такая логическая операция не найдена %s\n", tarr[curtoken - 1].line, tarr[curtoken - 1].value);

      return -1;

   }

   return retv;

}

int Condition(char *id_str,int cnt) {                           //Функция, выделяющая логическое условие в ифе и репите

                                                               //Входные параметры: метка, которую записываем и ее номер

   int op;                                                     //Номер логической операции

   if (tarr[curtoken].token != OPENBRACKET) {           

      printf("Ошибка %d: Условия должно начинаться со скобки %s\n", tarr[curtoken].line, tarr[curtoken].line);

      return -1;

   }

   curtoken++;

   if (Expression()) {                                         //Далее должно идти выражение

      return -1;

   }

   if ((op = Logic()) == -1) {                                 //Потом знак сравнения

      return -1;                                                

   }

   if (Expression()) {                                         //Потом еще одно выражение

      return -1;

   }

   if (tarr[curtoken].token != CLOSEBRACKET) {            

      printf("Ошибка %d: Условие должно заканчиваться скобкой %s\n", tarr[curtoken].line, tarr[curtoken].line);

      return -1;

   }

   curtoken++;

   fprintf(outfile, ASMCONDITION, StrLogic[op], id_str, cnt);

   return 0;

}

int GetOp() {                                 //Функция, идентифицирующая текущую математическую операцию

   int i,                                                      

       retv = -1;                                              //Возвращаемое значение

   if (strlen(tarr[curtoken].value) > 2) {                     //Если длина операции больше 2, тогда ошибка

      return -1;

   }

   for (i=0; i < 8; i++) {                                     //Ищем текущую операцию в массиве операций

       if (!strcmp(tarr[curtoken].value, OpMath[i])) {

          retv = i;

          break;

       }

   }

   if (retv == -1) {                                           //Если не нашли, тогда возвращаем ошибку

      return -1;

   }

   curtoken++;

   return retv;

   

}

int GetPar(char **name, int *index, int *value, char **name1) { //Функция, возвращающая параметры переменной из строки

   if (tarr[curtoken].token == NUMBER) {                       //Если переменная - число, тогда возвращаем имя переменной

      *name1 = 0;

      *name  = 0;

      *index = 0;

      sscanf(tarr[curtoken].value, "%ld", value);

      curtoken ++;

      return 0;

   } else {                                                    //Иначе возвращаем имя и индекс

      return Variable(name, index, name1);

   }

}

int Expression() {                 //Функция, разбирающая арифметическое выражение

   int op;                                                     //Номер операции

   if (Factor()) {                                             //В левой части - выражение

      return -1;

   }

   while (1) {                                                 //Завускаем бесконечный цикл, т.к. в правой части

                                                               //может бесконечное число операндов

      if ((op = GetOp()) == -1) {                              //Между операндами математическая операция

         return 0;

      }

      if (op < 5) {                                            //Если код операции меньше 5, значит это одна из простых

         if (Factor()) {                                       //операций, после которой идет выражение

            return -1;

         }

      } else {

         printf("Ошибка %d: Данная операция недопустима %s\n", tarr[curtoken - 1].line, tarr[curtoken - 1].value);

         return -1;

      }

      fprintf(outfile, MathOpAsm[op]);                         //Записываем результат выполнения операции

   }

}

int Factor() {                            //Функция, разбирающая одну из частей

                                                               //выражения (левую или правую)

   char *name  = 0,                                            //Имя переменной

        *name1 = 0;                                            //Имя индексной переменной

   int  index,                                                 //Индекс переменной

        num;                                                   //Значение числа

   switch (tarr[curtoken].token) {                             //Анализируем текущий токен

      case OPENBRACKET:                                        //Выражение начинается со скобки (, значит дальше

           curtoken ++;                                        //идет еще одно выражение

           if (Expression() == -1) {                  

              return -1;

           }

           if (tarr[curtoken].token != CLOSEBRACKET) {

              printf("Ошибка %d: Нет закрывающей скобки %s\n", tarr[curtoken].line, tarr[curtoken].value);

              return -1;

           }

           curtoken ++;

           return 0;

      case OPERATOR:                                           //Выражение начинается со знака (-)

           curtoken ++;

           if (Expression() == -1) {

              return -1;

           }

           fprintf(outfile, ASMNEGATE);                        //Записываем инверсию операнда

           return 0;

      case NUMBER:                                             //Выражение начинается с переменной или числа

      case IDENT:

           if (GetPar(&name, &index, &num, &name1) == -1) {    //Получаем параметры переменной или числа

              return -1;

           }

           if (name==NULL) {                                   //Если имени нет, тогда это число, иначе переменная

              fprintf(outfile, ASMASSUME_NUM, num);

           } else {

              if (name1 == 0) {                                //Проверяем индекс - число это или переменная

                 fprintf(outfile, ASMASSUME_MEM,  name,  index);

              } else {

                 fprintf(outfile, ASMASSUME_MEM1, name1, index, name);

              }

           }  

           return 0;

      default:                                                 //По умолчанию ошибка

           return 0;

   }

}           

      

int IdentCheck(datahold *data, int datanum) {                   //Проверка переменной на зарегенность. Входные параметры

                                                               //структура, в которой ищем и размер этой структуры

   int i;                                                      //Счетчик

   for (i=0; i < datanum; i++) {                               //Поиск в массиве зарегенных переменных входной переменной

       if (!strcmp(data[i].name, tarr[curtoken].value)) {

          return i;

       }

   }

   return -1;

}

int Index(char **name1) {                     //Определение индекса переменной. Входной параметр

                                                               //указатель на идентификатор

   int  size  = 0;                                             //Размер переменной

   char *name = 0;                                             //Имя переменной

   if (tarr[curtoken].token != OPENSQBRACKET) {

      printf("Ошибка %d: Индексная переменная должна начинаться со скобки [ %\n", tarr[curtoken].line, tarr[curtoken].value);

      return -1;

   }

   curtoken ++;

   switch (tarr[curtoken].token) {

      case NUMBER:                                             //В скобках находится число

           sscanf(tarr[curtoken].value, "%ld", &size);         //Преобразуем число из строки

           curtoken ++;

           break;

      case IDENT:                                              //В скобках находится идентификатор

           if (Variable(name1, &size, &name) != -1) {          //Выделяем его параметры

              if (name == 0) {                                 //Если это индексная переменная, тогда ошибка

                 break;

              }

           }

      default:

           printf("Ошибка %d: В скобках должно быть число %s\n", tarr[curtoken].line, tarr[curtoken].value);

           return -1;

   }

   if (tarr[curtoken].token != CLOSESQBRACKET) {

      printf("%d: Индексная переменная должна заканчиваться скобкой ] %s\n", tarr[curtoken].line, tarr[curtoken].value);

      return -1;

   }

   curtoken ++;

   return size;

}

int Variable(char **name, int *index, char **name1) {           //Идентификация переменной индексная она или нет. Входные

                                                               //параметры: имя переменной, индекс и имя индекса

   int i;

   char *name2;                                                //Счетчик

   if (tarr[curtoken].token != IDENT) {                  

      printf("Ошибка %d: Переменная должна начинаться с буквы %s\n", tarr[curtoken].line, tarr[curtoken].value);

      return -1;

   }

   *name  = tarr[curtoken].value;                              //Запоминаем имя переменной

   if ((i = IdentCheck(data, datanum)) == -1) {

      printf("Внимание %d: Переменная не идентифицирована %s\n", tarr[curtoken].line, tarr[curtoken].value);

      return -1;

   }

   curtoken ++;

   if (tarr[curtoken].token == OPENSQBRACKET) {                //Если после ИД идет открывающая скобка, значит это индексная

      *index = Index(name1);                                   //переменная. Запоминаем индекс переменной

      if (*name1 == 0) {

         if (*index >= data[i].size) {                         //Если индекс превысил допустимые границы, значит ошибка

            printf("Ошибка %d: Индекс вышел за допустимые границы\n", tarr[curtoken].line);

            return -1;

         }

      }

   } else {                                                    //Иначе это число

      *index = 0;

      *name1 = 0;

   }

   return 0;

}

int Code(int host, int count) {                 //Обработка вложенных операторов. Входные переменные: хозяин,

                                                               //и номер метки

   curtoken++;                                                 //Запускаем цикл обработки вложенных операторов

   while (1) {

      if (Statement(host, count) == -1) {                      //Обрабатываем вложенные операторы

         return -1;

      }

      if (tarr[curtoken].token == END) {                       //Если закрывающая скобка }, тогда выход

         break;

      }

   }

   curtoken++;

   return 0;

}

                                                               //Процедура обработки цикла Repeat-Until. Входной параметр

int RepeatUntil(int rcount) {                                   //номер цикла в программе

   curtoken ++;

   rcounter ++;                                                //Увеличиваем количество циклов на один

   fprintf(outfile, ASMREPEAT, rcount);                        //Записываем стартовую метку

   if (Statement(HOSTREPEAT, rcount) == -1) {                  //Обрабатываем вложенные операторы

      return -1;

   }

   if (tarr[curtoken].token != UNTIL) {

      printf("Ошибка %d: После выражения должен идти until %s\n", tarr[curtoken].line, tarr[curtoken].value);

      return -1;

   }

   curtoken ++;

   if (Condition("repeat", rcount) == -1) {                    //Обрабатываем условие завершения работы цикла

      return -1;

   }

   if (tarr[curtoken].token != DOTCOMMA) {

      printf("Ошибка %d: Пропущена точка с запятой %s\n", tarr[curtoken - 1].line, tarr[curtoken].value);

      return -1;

      }

   curtoken ++;

   fprintf(outfile, ASMUNTIL, rcount, rcount);                 //Записываем метку окончания цикла

   return 0;

}

int IfElse(int ifcount, int host, int count) {                  //Процедура обработки условного оператора if-else. Входные

                                                               //параметры номер ифа, хозяин и номер метки

   curtoken++;

   if (Condition("endif", ifcount) == -1) {                    //Сперва должно идти условие

      return -1;

   }

   ifcounter++;

   if (Statement(host, count) == -1) {                         //Далее блок операторов

      return -1;

   }

   if (tarr[curtoken].token == ELSE) {                        //Если есть часть else, то обработаем и ее

      fprintf(outfile, ASMIF_ELSE, "endelse", ifcount, "endif", ifcount);

      curtoken ++;

      if (Statement(host, count) == -1) {                     //Обработка блока операторов

         return -1;

      }

      fprintf(outfile, ASMEND_IF, "endelse", ifcount);        //Записываем метки окончания условного оператора

   } else {

      fprintf(outfile, ASMEND_IF, "endif",   ifcount);

   }

   return 0;

}

                                                               

int ForDo(int forcount) {                                       //Процедура обработки цикла for. Входные параметры:

                                                               //номер цикла

   int op;                                                     //Номер операции

   curtoken++;

   fcounter ++;                                                //Увеличиваем количество for`ов

   if (tarr[curtoken].token != OPENBRACKET) {

      printf("Ошибка %d: После for должна идти открывающая скобка %s\n", tarr[curtoken].line, tarr[curtoken].value);

      return -1;

   }

   curtoken ++;                                                //Сначала идет начальное условие

   if ((tarr[curtoken].token != IDENT) || (Statement(HOSTOTHER, forcount) == -1)) {

      return -1;

   }

   fprintf(outfile, ASMFOR, forcount);                         //Далее идет условие выхода их цикла

   if (Expression()) {                                         //Потом должно идти выражение

      return -1;

   }

   if ((op = Logic()) == -1) {                                 //Потом знак сравнения

      return -1;                                                

   }

   if (Expression()) {                                         //Потом еще одно выражение

      return -1;

   }

   fprintf(outfile, ASMCONDITION, StrLogic[op], "endfor", forcount);

   if (tarr[curtoken].token != DOTCOMMA) {

      printf("Ошибка %d: Не хватает точки с запятой %s\n", tarr[curtoken].line, tarr[curtoken-1].value);

      return -1;

   }

   curtoken++;                                                 //Потом выражение

   if ((tarr[curtoken].token != IDENT) || (Statement(HOSTOTHER, forcount) == -1)) {

      return -1;

   }

   if (tarr[curtoken].token != CLOSEBRACKET) {

      printf("Ошибка %d: Нет закрывающей скобки %s\n", tarr[curtoken].line, tarr[curtoken].value);

      return -1;

   }

   curtoken++;

   if (Statement(HOSTFOR, forcount) == -1) {                   //Потом обработка блока операторов

      return -1;

   }

   fprintf(outfile, ASMENDFOR, forcount, forcount);            //Запись в файл метки окончания цикла

   return 0;

}

int WhileDo(int rcount) {                                       //Процедура обработки цикла while

                                                               //Входной параметр номер цикла

   curtoken ++;

   wcounter ++;

   fprintf(outfile, ASMWHILE, rcount);

   if (Condition("endwhile", rcount) == -1) {                  //Обрабатываем условие завершения цикла

      return -1;

   }

   if (Statement(HOSTWHILE, rcount) == -1) {                   //Обрабатываем вложенные операторы

      return -1;

   }

   fprintf(outfile, ASMENDWHILE, rcount, rcount);

   return 0;

}

int Statement(int host, int count) {              //Основная функция синтаксического анализатора

                                                               //Входные параметры: хозяин и номер метки

   int  type,                                                  //Тип токена

        index,                                                 //Индекс переменной

        op;                                                    //Номер операции

   char *name  = 0,                                            //Имя индексной переменной

        *name1 = 0;                                            //Имя индекса, если там переменная

   switch (tarr[curtoken].token) {

                                                               //Операторные скобки {}

      case START:

           return Code(host, count);

      case IF:                                                 //Условный оператор if

           if (IfElse(ifcounter, host, count) == -1) {

              return -1;

           }

           return 0;

      case REPEAT:                                             //Оператор цикла repeat

           if (RepeatUntil(rcounter) == -1) {

              return -1;

           }

           return 0;

      case FOR:                                                //Оператор цикла for

           if (ForDo(fcounter) == -1) {

              return -1;

           }

           return 0;

      case WHILE:                                              //Оператор цикла while

           if (WhileDo(wcounter) == -1) {

              return -1;

           }

           return 0;

      case INT:                                                //Инициализация переменной

      case ARRAY:

           type = tarr[curtoken].token;                        //Сразу можем обработать несколько переменных

           while (1) {

              curtoken ++;

              if (tarr[curtoken].token != IDENT) {          

                 printf("Ошибка %d: После int и array должно идти имя переменной %s\n", tarr[curtoken].line, tarr[curtoken].value);

                 return -1;

              }

              if (IdentCheck(data, datanum) != -1) {

                 printf("Ошибка %d: Данная переменная уже зарегестрирована %s\n", tarr[curtoken].line, tarr[curtoken].value);

                 return -1;

              }

              name = tarr[curtoken].value;

              curtoken++;

              switch (type) {                                  //Проверяем тип переменной

                 case INT:                                     //Целый тип

                      index = 1;

                      break;

                 case ARRAY:                                   //Или массив

                      if ((index = Index(&name)) == -1) {

                         return -1;

                      }

                      break;

              }

              if ((data = realloc(data, (datanum + 1) * sizeof(datahold))) == 0) {  

                 printf("Недостаточно памяти");                                     

                 return -1;

              }

              data[datanum].name = name;                       //Записываем в таблицу переменных

              data[datanum].size = index;                      //новую переменную

              datanum ++;

              if (tarr[curtoken].token == COMMA) {             //Проверяем, есть ли запятая, если да, то обработаем еще одну

                 continue;                                     //переменную

              }

              break;

           }

           if (tarr[curtoken].token != DOTCOMMA) {

             printf("%d: Нет точки с запятой %s\n", tarr[curtoken - 1].line, tarr[curtoken].value);

             return -1;

           }

           curtoken++;

           return 0;

      case IDENT:                                              //Переменная

           if (Variable(&name, &index, &name1) == -1) {        //Определяем индекс и имя переменной

              curtoken ++;                                     //Может быть это процедура

              if (tarr[curtoken].token != OPENBRACKET) {

                 printf("%d: Нет открывающей скобки %s\n", tarr[curtoken - 1].line, tarr[curtoken].value);

                 return -1;

              }

              while (1) {                                      //Обрабатываем параметры процедуры

                 curtoken ++;

                 if ((tarr[curtoken].token != IDENT) && tarr[curtoken].token != NUMBER) {

                    printf("Внимание %d: Возможно в скобках переменная %s\n", tarr[curtoken - 1].line, tarr[curtoken].value);

                    break;

                 }

                 if (Expression() == -1) {                     //Параметром может быть выражение

                    return -1;

                 }

                 if (tarr[curtoken].token != COMMA) {

                    printf("Внимание %d: Возможно в скобках запятая %s\n", tarr[curtoken - 1].line, tarr[curtoken].value);

                    break;

                 }

              }

              if (tarr[curtoken].token != CLOSEBRACKET) {

                 printf("%d: Нет закрывающей скобки %s\n", tarr[curtoken - 1].line, tarr[curtoken].value);

                 return -1;

              }

              curtoken ++;

              if (tarr[curtoken].token != DOTCOMMA) {

                 printf("%d: Нет точки с запятой %s\n", tarr[curtoken - 1].line, tarr[curtoken].value);

                 return -1;

              }

              curtoken ++;

              fprintf(outfile, ASMCALL, name);

              return 0;

           }

           switch (tarr[curtoken].token) {                     //Проверка на тип операции ( ++ -- **)

                case ASSUME:                    //далее идет = выражение

                     curtoken ++;

                     if (Expression() == -1) {                 //Потом идет выражение

                        return -1;

                     }

                     break;

                case OPERATOR:                                 //далее идет = (++ или -- или **)

                     if (name1 == 0) {

                        fprintf(outfile, ASMASSUME_MEM,  name,  index);

                     } else {

                        fprintf(outfile, ASMASSUME_MEM1, name1, index, name);

                     }

                     if ((op = GetOp()) != -1) {               //Между ними математическая операция

                        if (op > 4) {

                           fprintf(outfile, MathOpAsm[op]);

                           break;

                        }

                     }

                default:

                    printf("%d: Отсутствует знак присваивания %s %d\n", tarr[curtoken].line, tarr[curtoken].value, curtoken);

                    return -1;

           }

           if (tarr[curtoken].token != DOTCOMMA) {

              printf("%d: Нет точки с запятой %s\n", tarr[curtoken - 1].line, tarr[curtoken].value);

              return -1;

           }

           curtoken ++;

           if (name1 == 0) {

              fprintf(outfile, ASMSTATEMENT,  name,  index);

           } else {

              fprintf(outfile, ASMSTATEMENT1, name1, index, name);

           }

           return 0;

      case READ:                                               //Операторы ввода и вывода данных

      case WRITE:

           type = tarr[curtoken].token;

           while (1) {                                         //Можно вывести или ввести несколько выражений

              curtoken ++;

              switch (type) {

      

                    case READ:

                         if (Variable(&name, &index, &name1) == -1) {

                            return -1;

                         }

                         if (name1 == 0) {

                fprintf(outfile, ASMREAD,  name,  index);

                         } else {

                            fprintf(outfile, ASMREAD1, name1, index, name);

                         }

           break;

                    case WRITE:

                         if (Expression() == -1) {             //Опеределяем выражение и выводим его

                            return -1;

                         }

                         fprintf(outfile, ASMWRITE);

           break;

              }

              if (tarr[curtoken].token == COMMA) {             //Проверяем, есть ли запятая, если да, то обработаем еще одну

                 continue;                                     //переменную

              }

       break;

           }

           if (tarr[curtoken].token != DOTCOMMA) {

              printf("%d: Нет точки с запятой %s\n", tarr[curtoken - 1].line, tarr[curtoken].value);

             return -1;

           }

           curtoken ++;

           return 0;

      case WRITELN:                                            //Перевод строки

           fprintf(outfile, ASMLN);

           curtoken ++;

           return 0;

      case DOTCOMMA:                                           //Пустой оператор ;

           curtoken ++;

           return 0;

                                                               //Оператор continue

      case CONTINUE:                                           //Проверяем какой цикл вызывал и записываем его метку

           switch (host) {

              case HOSTWHILE:

                   fprintf(outfile, ASMJMP, "while", count);

                   break;

              case HOSTREPEAT:

                   fprintf(outfile, ASMJMP, "repeat", count);

                   break;

              case HOSTFOR:

                   fprintf(outfile, ASMJMP, "for", count);

                   break;

              default:

                   printf("%d: Оператор continue должен находиться внутри цикла\n", tarr[curtoken - 1].line);

                   return -1;

           }             

           curtoken ++;

           if (tarr[curtoken].token != DOTCOMMA) {

             printf("%d: Нет тоqчки с запятой %s\n", tarr[curtoken - 1].line, tarr[curtoken].value);

             return -1;

           }

           curtoken ++;

           return 0;

      case BREAK:                                              //Оператор break

           switch (host) {                                     //Проверяем какой цикл вызывад и записываем его метку

              case HOSTWHILE:

                   fprintf(outfile, ASMJMP, "endwhile", count);

                   break;

              case HOSTREPEAT:

                   fprintf(outfile, ASMJMP, "until", count);

                   break;

              case HOSTFOR:

                   fprintf(outfile, ASMJMP, "endfor", count);

                   break;

              default:

                   printf("%d: Оператор break должен находиться внутри цикла\n", tarr[curtoken - 1].line);

                   return -1;

           }             

           curtoken ++;

           if (tarr[curtoken].token != DOTCOMMA) {

             printf("%d: Нет точки с запятой %s\n", tarr[curtoken - 1].line, tarr[curtoken].value);

             return -1;

           }

           curtoken ++;

           return 0;

      default:

           printf("%d: Неизвестный оператор %s\n", tarr[curtoken].line, tarr[curtoken].value);

           return -1;

   }

}

int DataOut(FILE *outfile) {                     //Запись сегмента данных

   int i;

   fprintf(outfile,"%s", DataHeader);

   for (i=0; i < datanum; i++){

       if (data[i].size == 1) {

          fprintf(outfile,"%s dd 0\n", data[i].name);

       } else {

          fprintf(outfile,"%s times %d dd 0\n", data[i].name, data[i].size);

       }

   }

   fclose(outfile);

   return 0;

}

int Parse() {                              //Инициализация синтаксического анализатора

   int tmp   = 0,                                              //Переменная, считающая количество переменных процедуры

       tmp1  = 0,                                              //Проверка на наличие имени main

       count = 0;                                              //Счетчик

   while (curtoken < tokennum) {                               //Обрабатываем все токены

      if (tarr[curtoken].token != PROCEDURE) {

         printf("%d: Сначала идет объявление процедуры %s\n", tarr[curtoken].line, tarr[curtoken].value);

         return -1;

      }

      curtoken ++;

      if (tarr[curtoken].token != IDENT) {

         printf("%d: Процедура должна носить имя %s\n", tarr[curtoken].line, tarr[curtoken].value);

         return -1;

      }

      if (IdentCheck(proch, procnum) != -1) {

         printf("%d: Такая процедура уже зарегестрирована %s\n", tarr[curtoken].line, tarr[curtoken].value);

         return -1;

      }

      if ((proch = realloc(proch, (procnum + 1) * sizeof(datahold))) == 0) {    //Записываем в таблицу переменных

         printf("Недостаточно памяти");                                         //новую переменную

         return -1;

      }

      proch[procnum].name = tarr[curtoken].value;

      curtoken ++;

      fprintf(outfile, ASMPROCSTART, proch[procnum].name);

      if (!strcmp(proch[procnum].name, "main")) {              //Если имя main, значит tmp = 1

         tmp1 = 1;

      }

      if (tarr[curtoken].token != OPENBRACKET) {

         printf("%d: После procedure должна идти открывающая скобка %s\n", tarr[curtoken].line, tarr[curtoken].value);

         return -1;

      }

      while (1) {                                              //Обрабатываем переменные процедуры

         tmp = datanum;

         curtoken ++;

         if (tarr[curtoken].token == INT) {                    //Тип переменной

            if (Statement(1, 0) == -1) {

               return -1;

            }

            curtoken --;

         } else {

            break;

         }                                                     //Записываем несколько переменных

         while (tmp != datanum) {

 

           count ++;

           fprintf(outfile, ASMVARIABLE, 4 + 4 * (datanum - tmp), data[tmp]);

           tmp ++;

         }

      }

      proch[procnum].size = count;

      procnum  ++;

      if (tarr[curtoken].token != CLOSEBRACKET) {

         printf("%d: Нет закрывающей скобки %s\n", tarr[curtoken].line, tarr[curtoken].value);

         return -1;

      }

      curtoken ++;

      if (tarr[curtoken].token != START) {

         printf("%d: Нет открывающей скобки %s\n", tarr[curtoken].line, tarr[curtoken].value);

         return -1;

      }

      if ((Statement(1, 0) == -1)) {                           //Обрабатываем тело процедуры

         return -1;

      }

      fprintf(outfile, ASMPROCEND);                            //Записываем конец процедуры

      count = 0;

   }

   if (tmp1 == 0) {

      printf("Ошибка: Главная процедура должна называться main\n");

      return -1;

   }  

   DataOut(outfile);

   printf("Синтаксический анализ выполнен успешно\n");

   return 0;

}

int RunNasmW() {                              //Запуск насма

   int retc;

   char command[256];

   sprintf(command,"nasmw -f obj %s", outname);

   retc = system(command);

   return retc;

}

int RunTlink32() {                             //Запуск компоновщика

   int retc;

   char command[256],

        *tmp;

   tmp = malloc(128);

   strncpy(tmp, outname, strlen(outname) - 3);

   strcat (tmp, "obj");

   sprintf(command, "tlink32 %s,,,import32 mylib", tmp);

   retc = system(command);

   return retc;

}

int OtherOut() {                                //Запись таблицы символических имен в файл

   char tmp[128];

   memset(tmp, 0, 128);

   strncpy(tmp, outname, strlen(outname) - 3);

   strcat (tmp, "er");

   if ((outfile = fopen(tmp, "w+")) == NULL) {

      printf("Невозможно создать файл для записи таблицы символических имен");

      return 0;

   }

   fprintf(outfile, "   Value   | Token | Line\n");

   for (count = 0; count < tokennum; count++) {

       fprintf(outfile, "%10.10s  %5.1d  %5.1d\n", tarr[count].value, tarr[count].token, tarr[count].line);

   }

   fprintf(outfile, "\n\n   Name   |   Size\n");

   for (count = 0; count < datanum; count++) {

       fprintf(outfile, "%10.10s  %5.1d\n", data[count].name, data[count].size);

   }

   fprintf(outfile, "\n\n   Name   |   Size\n");

   for (count = 0; count < procnum; count++) {

       fprintf(outfile, "%10.10s  %5.1d\n", proch[count].name, proch[count].size);

   }

   fclose(outfile);

   return 0;

}

int main(int argc, char* argv[]) {                       //Основная процедура

   char *buffer;

   int  actlen;

   if (argc == 1) {

      printf("Введите имя файла\n");

      return 0;

   }

   if ((inpfile = fopen(argv[1], "rb")) == NULL) {

      printf("Введите корректное имя файла\n");

      return 0;

   }

   buffer = malloc(FileSize(inpfile) + 1);

   strncpy(outname, argv[1], strlen(argv[1])-strlen(strrchr(argv[1], '.')) + 1);

   strcat (outname, "asm");

   if ((outfile = fopen(outname, "w+")) == NULL) {

      printf("Невозможно создать выходной файл");

      return 0;

   }

   memset(buffer, 0, strlen(buffer));

   actlen = fread(buffer, 1, FileSize(inpfile), inpfile);

   if (actlen == 0) {

      printf("Размер файла равен 0");

      exit(0);

   }

   strncpy(buffer, buffer, FileSize(inpfile));

   fclose(inpfile);

   if (LexAnalyz(buffer) == -1) {

      return -1;

   }

   fprintf(outfile, CodeHeader);

   if (Parse() == -1) {

   OtherOut();

      return -1;

   }

   RunNasmW();

   RunTlink32();

   OtherOut();

   return 0;

}


файл axtoi.asm

 GLOBAL axtoi

 SEGMENT code USE32 CLASS=CODE

axtoi:

 xor edi,edi

comp:                     ;compare chars input string with digit

 cmp [eax+edi],byte '9'

 jg endcomp

 cmp [eax+edi],byte '0'

 jl endcomp

 inc edi

 cmp [eax+edi],byte 0

 jne comp

endcomp:

 mov [tm1],edi             ;bring in ebx real quantity digit

 xor edi,edi

 mov ecx,10

 mov [tmp],dword 0

 mov ebx,eax

 perev:                    ;procedure of transformation chars in digit

 cmp edi,[tm1]             ;if edi >= ebx then endpr

 jge endpr

 xor eax,eax

 mov al,[ebx+edi]        ;bring from memory digit

 sub al,'0'

 mov esi,edi             ;bring esi position digit in string

 inc esi

shift:                    ;multiplicate digit on 10 in degree here position in string

 cmp esi,[tm1]             ;if esi >= ebx then ends

 jge ends

 mul ecx

 inc esi

 jmp shift

ends:

 add eax,[tmp]           ;save temporary result

 mov [tmp],eax

 inc edi

 jmp perev

endpr:

 mov eax,[tmp]           ;output result

 ret

 SEGMENT data USE32 CLASS=DATA

 

tmp dd 0

tm1 dd 0

файл itox.asm

 GLOBAL itox

 EXTERN stdwrite, lfwrite

 

;  GROUP DGROUP code data

 SEGMENT code USE32 CLASS=CODE

 

itox:                     ;procedure of output digits

 pusha

 mov edi,lmes

 mov edx,mess

 call stdwrite

 popa

;  pusha

 mov ebx,10              ;devider

 xor esi,esi             ;counter

divs:

 xor edx,edx             ;reset edx

 div ebx                 ;division eax on ebx

 add dl,'0'

 push edx

 inc esi                 ;increment counter

 cmp eax,0               ;if eax<>0 then divs

 jne divs

 mov [tmp],dword 0

undivs:

 pop edx

 mov [tmp],dl

 mov edx,tmp

 mov edi,1

 call stdwrite

 dec esi

 cmp esi,0               ;if esi<>0 then undivs

 jne undivs

;  popa

 mov edi,2

 mov edx,mes

 call stdwrite

 ret

 SEGMENT data USE32 CLASS=DATA

 

tmp dd 0

mess db 'Output number: ',0

lmes equ $-mess

mes db 13,10


файл strexit.asm

 GLOBAL stdexit

 EXTERN ExitProcess

  SEGMENT code USE32 CLASS=CODE

 stdexit:

 push dword 0

 call ExitProcess

 ret

файл stdwrite.asm

 GLOBAL stdwrite

 EXTERN GetStdHandle, WriteFile

   SEGMENT code USE32 CLASS=CODE

 stdwrite:

 push dword -11

 call GetStdHandle

 push dword 0

 push dword actlen

 push dword edi

 push dword edx

 push dword eax

 call WriteFile

 mov eax,[actlen]

 ret

 

 SEGMENT data USE32 CLASS=DATA

actlen db 0

файл stdread.asm

 GLOBAL stdread

 EXTERN GetStdHandle, ReadFile, axtoi, stdwrite

 

 SEGMENT code USE32 CLASS=CODE

 

stdread:

;  pusha

 mov edi,lmes

 mov edx,mess

 call stdwrite

 push dword -10

 call GetStdHandle

 push dword 0

 push dword actlen

 push dword 10

 push dword string

 push dword eax

 call ReadFile

 mov eax,string

;  popa

 call axtoi

 ret

 SEGMENT data USE32 CLASS=DATA

actlen dd 0

string dd 0

mess db 'Please input number: ',0

lmes equ $-mess


Пример работы

Текст программы:

procedure main() {                    объявление главной процедуры

int a1, a3, i, j;                     объявление переменных

int a2;

array b[6], a4[10];

i     = 5;                            присваивание переменных

a4[i] = 3 + 1 + 2 * 2 % 7;

a4[i] ++;

other();                              вызов процедуры other()

for (i = 0; i<10; i++;) {             цикл for

 for (j = 0; j<10; j++;) {           вложенный цикл for

   write j*i;                        вывод переменной

 }

 writeln;                            перевод строки

}

repeat {                              цикл repeat-until

 i++;                                инкремент переменной

 read b[i];                          ввод с клавиатуры числа

 if (b[i] == 14) {                   если введеное число равно 14, тогда выводим его и завершаем цикл

    write b[i];

    break;

 } else {

    if (b[i] == 20) {                если оно равно 10 тогда выводим его и продолжаем цикл без проверки условия

       write b[i];

       continue;

   }

 }

 write b[i];

} until (b[i] % 10 == 0);             проверка условия выхода из цикла

writeln;

i = 1;

writeln;

while (i < 10) {                      цикл while

 i++;

 write i;

 j = 0;

 while (j < 10) {

   j++;

   write j;

   if (j == 5) {

      continue;

   }

 }

 writeln;

}

other1(5 + 7, 10, 15, j + 11);       вызов процедуры с параметрами

}

procedure other() {                  объявление процедуры other без параметров

 int a;

a = 0;

write a+10;

 

}

procedure other1(int a10, a11, a12, a14;) {   обявление процедуры с параметрами

write a10, a11, a12, a14;

}


Результат на ассемблере:

EXTERN stdexit, stdread, itox, lfwrite

segment .text USE32 CLASS=CODE

..start:

call main

call stdexit

main:

push ebp

mov ebp, esp

push dword 5

pop dword [i+4*0]

push dword 3

push dword 1

pop ebx

pop eax

add eax,ebx

push eax

push dword 2

pop ebx

pop eax

add eax,ebx

push eax

push dword 2

pop ebx

pop eax

mul ebx

push eax

push dword 7

pop ebx

pop eax

xor edx,edx

div ebx

push edx

mov edi, [i+4*0]

pop dword [a4+4*edi]

mov edi,[i+4*0]

push dword [a4+4*edi]

pop ebx

mov eax,1

add eax,ebx

push eax

mov edi, [i+4*0]

pop dword [a4+4*edi]

call other

push dword 0

pop dword [i+4*0]

for_0:

push dword [i+4*0]

push dword 10

pop ebx

pop eax

cmp eax,ebx

jge near endfor_0

push dword [i+4*0]

pop ebx

mov eax,1

add eax,ebx

push eax

pop dword [i+4*0]

push dword 0

pop dword [j+4*0]

for_1:

push dword [j+4*0]

push dword 10

pop ebx

pop eax

cmp eax,ebx

jge near endfor_1

push dword [j+4*0]

pop ebx

mov eax,1

add eax,ebx

push eax

pop dword [j+4*0]

push dword [j+4*0]

push dword [i+4*0]

pop ebx

pop eax

mul ebx

push eax

pop eax

call itox

jmp near for_1

endfor_1:

call lfwrite

jmp near for_0

endfor_0:

repeat_0:

push dword [i+4*0]

pop ebx

mov eax,1

add eax,ebx

push eax

pop dword [i+4*0]

call stdread

mov edi,[i+4*0]

mov [b+4*edi],eax

mov edi,[i+4*0]

push dword [b+4*edi]

push dword 14

pop ebx

pop eax

cmp eax,ebx

jne near endif_0

mov edi,[i+4*0]

push dword [b+4*edi]

pop eax

call itox

jmp near until_0

jmp endelse_0

endif_0:

mov edi,[i+4*0]

push dword [b+4*edi]

push dword 10

pop ebx

pop eax

cmp eax,ebx

jne near endif_1

mov edi,[i+4*0]

push dword [b+4*edi]

pop eax

call itox

jmp near repeat_0

endif_1:

endelse_0:

mov edi,[i+4*0]

push dword [b+4*edi]

pop eax

call itox

mov edi,[i+4*0]

push dword [b+4*edi]

push dword 10

pop ebx

pop eax

xor edx,edx

div ebx

push edx

push dword 0

pop ebx

pop eax

cmp eax,ebx

jne near repeat_0

until_0:

call lfwrite

push dword 1

pop dword [i+4*0]

call lfwrite

while_0:

push dword [i+4*0]

push dword 10

pop ebx

pop eax

cmp eax,ebx

jge near endwhile_0

push dword [i+4*0]

pop ebx

mov eax,1

add eax,ebx

push eax

pop dword [i+4*0]

push dword [i+4*0]

pop eax

call itox

push dword 0

pop dword [j+4*0]

while_1:

push dword [j+4*0]

push dword 10

pop ebx

pop eax

cmp eax,ebx

jge near endwhile_1

push dword [j+4*0]

pop ebx

mov eax,1

add eax,ebx

push eax

pop dword [j+4*0]

push dword [j+4*0]

pop eax

call itox

push dword [j+4*0]

push dword 5

pop ebx

pop eax

cmp eax,ebx

jne near endif_2

jmp near while_1

endif_2:

jmp while_1

endwhile_1:

call lfwrite

jmp while_0

endwhile_0:

push dword 5

push dword 7

pop ebx

pop eax

add eax,ebx

push eax

push dword 10

push dword 15

push dword [j+4*0]

push dword 11

pop ebx

pop eax

add eax,ebx

push eax

call other1

mov esp,ebp

pop ebp

ret

other:

push ebp

mov ebp, esp

push dword 0

pop dword [a+4*0]

push dword [a+4*0]

push dword 10

pop ebx

pop eax

add eax,ebx

push eax

pop eax

call itox

mov esp,ebp

pop ebp

ret

other1:

push ebp

mov ebp, esp

mov eax, [ebp + 20]

mov [a10], eax

mov eax, [ebp + 16]

mov [a11], eax

mov eax, [ebp + 12]

mov [a12], eax

mov eax, [ebp + 8]

mov [a14], eax

push dword [a10+4*0]

pop eax

call itox

push dword [a11+4*0]

pop eax

call itox

push dword [a12+4*0]

pop eax

call itox

push dword [a14+4*0]

pop eax

call itox

mov esp,ebp

pop ebp

ret

segment .data USE32

a1 dd 0

a3 dd 0

i dd 0

j dd 0

a2 dd 0

b times 6 dd 0

a4 times 10 dd 0

a dd 0

a10 dd 0

a11 dd 0

a12 dd 0

a14 dd 0


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

1. Ахо А., Сети Р., Ульман Д. Компиляторы: принципы, технологии и инструменты. : Пер. с англ. – М.: Издательский дом “Вильямс”, 2003. – 768 с.: ил




1. 1 Структура психологические основы деятельности следователя в предварительном следствии Профессионал
2. на тему- Аргентина в международных экономических отношениях Курс
3. Национальные особоенности- брэнд для внутреннего употребления
4. Антропологические основания этики как философии счастья
5. орієнтована Дати- 23 вересня 2013 ~ 03 листопада 2013 року ~ 6 тижнів гр.html
6. Лекция 9. Скалярное векторное и смешанное произведения векторов 9
7. Проблемы разработки ПО
8. исторические предпосылки возникновения философии в древней Греции
9. Танец с драконами
10. ЛЕКЦИЯ ПО ТЕМЕ 26 ПОЛИТИЧЕСКАЯ И ГОСУДАРСТВЕННАЯ ВЛАСТЬ- Понятие политической власти- Наиболее в