Інтерпретатори. Принципи написання інтерпретаторів на прикладі написання програми, що виконує команди і директиви язика асемблера процесора 8086

Страницы работы

Содержание работы

Міністерство освіти і науки України

Національний технічний університет

“Харківський політехнічний інститут”

Кафедра обчислювальної техніки та програмування

Лабораторна робота №6

“Інтерпретатори”

                                                                                Виконав:

                                                                                студент групи АП-30б

                                                                                Шпіка П. М.

                                                                                Перевірив:

                                                                                Межерицький С. Г.

Харків 2002

1.  Тема роботи: Інтерпретатори.

2.  Мета роботи: Освоїти принципи написання інтерпретаторів на прикладі написання програми, що виконує команди і директиви язика асемблера процесора 8086.

3.  Постановка задачі: Необхідно розробити програму, що виконує команди язика асемблер.

4.  Розробка алгоритму рішення задачі:

4.1.  Вибір перемінних.

Тут розглядаються тільки основні перемінні, котрі є найбільш основними для даної програми. Імена перемінних, їхній тип і функціональне призначення приведені в таблиці 1.

Таблиця 1.

ім'я

тип

призначення

*mnemonics[]

*registers[]

opcode

op1num

op2num

regval

[sizeof(registers/ sizeof(char *)]

char

char

int

int

int

int

Покажчик на елемент масиву mnemonics. Цей масив містить найменування команд язика асемблера, що зустрічаються у вихідному тексті.

--//--

Індекс для масиву mnemonics.

--//-- registers

--//-- registers

Масив вмістів імітованих регістрів.

4.2.  Опис структури програми:

Імена функцій, їхній тип і призначення приведені в таблиці 2.

Таблиця 2.

ім'я

тип

Призначення

Strtoi

Strupcase

Strcomp

*parse

findstr

push

pop

execcmd

main

int

void

char

char

int

void

int

void

void

Порівняння виділеної лексеми з десятковим числом. У випадку позитивного результату повертає значення 0. Перетворення рядкових символів у прописні.

Порівняння двох рядків.

Виділення лексеми з рядка.

Пошук рядка в масиві рядків.

У випадку присутності повертає її індекс у масиві, у противному випадку: -1.

Імітація занесення в стек.

Імітація узяття зі стека.

Виконання команд.

Головна програма.

Загальний алгоритм рішення задачі такий:

1)  Вводиться з клавіатури команда (рядок).

2)  Якщо рядок порожній, то вихід із програми.

3)  Виробляється синтаксичний аналіз введеного рядка.

4)  Якщо немає помилок, команда виконується, у противному випадку – перехід до пункту 1.

5.  Текст програми interp.c:

#include <stdio.h>

#define PT_EOST 0

#define PT_SIGN 1

#define PT_WORD 2

#define INUL ((int *) 0)

#define MAXSTR 64

#define STACKLEN 16

#define OP_MOV   0

#define OP_DEC   1

#define OP_INC   2

#define OP_ADD   3

#define OP_SUB   4

#define OP_PUSH  5

#define OP_POP   6

#define OP_RET   7

#define OP_OR    8

#define OP_XOR   9

#define OP_AND   10

#define OP_NOT   11

char *registers[] = {

    "AX",

    "BX",

    "CX",

    "DX",

    "SP",

#define RSP 4

    "BP",

    "SI",

    "DI",

    "IP",

#define RIP 8

    "IMM"

#define RIMM 9

};

char *mnemonics[] = {

    "MOV",

    "DEC",

    "INC",

    "ADD",

    "SUB",

    "PUSH",

    "POP",

    "RET",

    "OR",

    "XOR",

    "AND",

    "NOT"

    ""

};

char operandcount[] = {2, 1, 1, 2, 2, 1, 1, 0, 2, 2,2,1};

char signs[] = "~!@#$%^&*()_)+|`\\=,./<>?;':\"";

char separators[] = "\t \r\n";

int regval[sizeof(registers) / sizeof(char *)];

char parsetyp = 0;

int stack[STACKLEN];

char pswz = 0;

char lexbuf[MAXSTR];

char cmdbuf[MAXSTR];

int strtoi(char *s, int *i)

{

    int sign;

    int val;

    val = 0;

    if(!*s)

        return -1;

    if(*s == '-')

    {

        sign = -1;

        s++;

    }

    else

        sign = 1;

    while(*s)

    {

        if(*s < '0') return -1;

        if(*s > '9') return -1;

        val *= 10;

        val += *s - '0';

        *s++;

    }

    *i = val * sign;

    return 0;

}

void push(int it)

{

   if(((unsigned) regval[RSP]) > STACKLEN)

   {

        printf("Invalid SP value. Stack pointer is adjusted\n");

        regval[RSP] = 0;

   }

   stack[regval[RSP]] = it;

}

int pop(void)

{

   if(((unsigned) regval[RSP]) > STACKLEN)

   {

        printf("Invalid SP value. Stack pointer is adjusted\n");

        regval[RSP] = 0;

   }

   return stack[--regval[RSP]];

}

void strupcase(char *s)

{

    while(*s)

    {

        if((*s > ('a' - 1)) && (*s < ('z'+1)))

            *s -= ('z' - 'Z');

         s++;

    }

}

char strcomp(char *s1, char *s2)

{

    while(*s1)

    {

        if(*s1 != *s2)

            return 0;

        s1++;

        s2++;

    }

    if(*s2)

        return 0;

    return 1;

}

void execcmd(char code, int *op1, int *op2)

{

    switch (code)

    {

        case  OP_MOV :   *op1 = *op2;                          break;

        case  OP_DEC :   (*op1)--;     pswz = (*op1 == 0);     break;

        case  OP_INC :   (*op1)++;     pswz = (*op1 == 0);     break;

        case  OP_ADD :   *op1 += *op2; pswz = (*op1 == 0);     break;

Похожие материалы

Информация о работе