Скачиваний:
11
Добавлен:
01.05.2014
Размер:
23.39 Кб
Скачать

// File:        GenAsm.cpp

// Purpose:     Генерация ассемблерного кода
//*****************************************************************************
#include "StdAfx.h"
#include "GenAsm.h"
#include "Utilities.h"
#include "TableMgr.h"
#include "Limits.h"
#include <assert.h>
//-----------------------------------------------------------------------------

CGenAsm::CGenAsm()
{
    m_pFile     = NULL;
    m_NextLabel = 0;
}

//-----------------------------------------------------------------------------

std::string CGenAsm::NewLabel()
{
    char buffer[128];
    sprintf(buffer, "_ASM_Label_%u", m_NextLabel++);
    return std::string(buffer);
}

//-----------------------------------------------------------------------------

const char * CGenAsm::GetConditionInstruction(TET_OPERATION op)
{
    switch (op)
    {
        case TET_OP_REL_E_F:  
        case TET_OP_REL_E  :  return "je";

        case TET_OP_REL_NE_F:
        case TET_OP_REL_NE :  return "jne";
        
        case TET_OP_REL_G_F:  return "ja";
        case TET_OP_REL_G  :  return "jg";

        case TET_OP_REL_GE_F: return "jae";
        case TET_OP_REL_GE :  return "jge";

        case TET_OP_REL_L_F:  return "jb";
        case TET_OP_REL_L  :  return "jl";

        case TET_OP_REL_LE_F: return "jbe";
        case TET_OP_REL_LE :  return "jle";

        default:
            assert(false);
            return "Error!!!";
    }
}

//-----------------------------------------------------------------------------

void CGenAsm::GenerateAsmFile(const char *FileName, CNameTable& NameTable, CTetradStream &Tetrads)
{
    m_pFile = fopen(FileName, "w");
    assert(m_pFile);
    if(!m_pFile) return;

    char sBuff[256];
    UTIL::GetTimeStr(sBuff, sizeof(sBuff));
    fprintf(m_pFile, ";  Файл создан: \t %s \n", sBuff);
    fprintf(m_pFile, "; --------------------------------------------\n");

    WriteAsmPrefix();
	WriteSegmentStack();
    WriteSegmentData(NameTable);
	WriteSegmentCode(Tetrads);

    fclose(m_pFile);
}
//-----------------------------------------------------------------------------
void CGenAsm::WriteAsmPrefix()
{
    fprintf(m_pFile, "\n");
    fprintf(m_pFile, "\n .286");
    fprintf(m_pFile, "\n DOSSEG");
    fprintf(m_pFile, "\n .MODEL SMALL");
    fprintf(m_pFile, "\n");
    fprintf(m_pFile, "\n EXTRN _write_char: PROC");
    fprintf(m_pFile, "\n EXTRN _write_int : PROC");
    fprintf(m_pFile, "\n EXTRN _write_flt : PROC");
    fprintf(m_pFile, "\n EXTRN _write_str : PROC");
    fprintf(m_pFile, "\n EXTRN _write_ln  : PROC");
    fprintf(m_pFile, "\n EXTRN _read_char : PROC");
    fprintf(m_pFile, "\n EXTRN _read_int  : PROC");
    fprintf(m_pFile, "\n EXTRN _read_flt  : PROC");
    fprintf(m_pFile, "\n EXTRN _read_str  : PROC");
    fprintf(m_pFile, "\n");
    fprintf(m_pFile, "\n EXTRN _copy_str  : PROC");
    fprintf(m_pFile, "\n EXTRN _concat_str: PROC");
}
//-----------------------------------------------------------------------------

void CGenAsm::WriteSegmentStack()
{
    /*
    fprintf(m_pFile, "\n; **************************************");
	fprintf(m_pFile, "\n; ********** Сегмент стека ************* \n");
	fprintf(m_pFile, "\n Stack_Seg	SEGMENT STACK");
	fprintf(m_pFile, "\n DB		4096 dup(0)");
	fprintf(m_pFile, "\n Stack_Seg	ENDS");
    */
}

//-----------------------------------------------------------------------------

void CGenAsm::WriteSegmentData(CNameTable& NameTable)
{
	fprintf(m_pFile, "\n");
	fprintf(m_pFile, "\n; **************************************");
    fprintf(m_pFile, "\n; *********** Сегмент данных ***********");
    fprintf(m_pFile, "\n");
    //fprintf(m_pFile, "\nData_Seg	SEGMENT\n");
    fprintf(m_pFile, "\n .DATA");

    char * sSize = NULL;
    char sBuff[512];
    bool bLiter, bTemp;
    unsigned index;
    for (CNameTable::iterator it = NameTable.begin(); it != NameTable.end(); ++it)
    {
        bLiter = it->second.bLiter;
        bTemp  = it->second.bTemp;
        index  = it->second.index;
        switch(it->second.type)
        {
            case TYPE_INTEGER:
                sSize = "DW";   // для Integer выделяется слово
                if (bLiter)
                    sprintf(sBuff, "%d", g_TableMgr.GetValueInt(index));
                else
                    sprintf(sBuff, "0h ; %s", bTemp ? "временная": g_TableMgr.IDLexem(index));

            break; 

            case TYPE_BOOLEAN:  // 1 байт
                sSize = "DB";
                if (bLiter)
                    sprintf(sBuff, "%d", g_TableMgr.GetValueBool(index) ? 1 : 0);
                else
                    sprintf(sBuff, "0h ; %s", bTemp ? "временная": g_TableMgr.IDLexem(index));

            break; 

            case TYPE_REAL:
                sSize = "DD";
                if (bLiter)
                    sprintf(sBuff, "%f", g_TableMgr.GetValueReal(index));
                else
                    sprintf(sBuff, "0h ; %s", bTemp ? "временная": g_TableMgr.IDLexem(index));
            break;

            case TYPE_STRING:
                sSize = "DB";
                if (bLiter)
                    sprintf(sBuff, "\"%s\",0", g_TableMgr.GetValueStr(index).c_str());
                else
                    sprintf(sBuff, "256 dup(0) ; %s", bTemp ? "временная" : g_TableMgr.IDLexem(index));
            break;

            case TYPE_CHAR:
                sSize = "DB";
                if (bLiter)
                    sprintf(sBuff, "'%c'", g_TableMgr.GetValueChar(index));
                else
                    sprintf(sBuff, "0 ; %s", bTemp ? "временная" : g_TableMgr.IDLexem(index));
            break;

            case TYPE_STACK:
                // Стек может встретиться только как явно объявленная переменная
                sSize = "DB";
                    if (bLiter)
                        assert(false);
                    else
                        sprintf(sBuff, "%d dup(0) ; %s", STACK_SIZE_BYTES, g_TableMgr.IDLexem(index));
            break;
        }
        // Собственно записываем объявление переменной
        fprintf(m_pFile, "\n%-16s %-10s %s", it->first.c_str(), sSize, sBuff);
    }
    //fprintf(m_pFile, "\n\nData_Seg	ENDS");
}

//-----------------------------------------------------------------------------

void CGenAsm::WriteSegmentCode(CTetradStream &Tetrads)
{
	fprintf(m_pFile, "\n");
	fprintf(m_pFile, "\n; **************************************");
	fprintf(m_pFile, "\n; ************* Сегмент кода ***********");
	fprintf(m_pFile, "\n");
//	fprintf(m_pFile, "\n Code_Seg		SEGMENT");
//	fprintf(m_pFile, "\n ASSUME CS: Code_Seg, DS: Data_Seg, SS: Stack_Seg");
//	fprintf(m_pFile, "\n main PROC");
//	fprintf(m_pFile, "\n");
//	fprintf(m_pFile, "\n; Инициализация сегмента данных (1 шт.)");
//	fprintf(m_pFile, "\n mov AX, Data_Seg");
//  fprintf(m_pFile, "\n mov DS, AX");

    fprintf(m_pFile, "\n .CODE");
    fprintf(m_pFile, "\n PUBLIC _asmentry");
	fprintf(m_pFile, "\n");
    fprintf(m_pFile, "\n _asmentry PROC");
	fprintf(m_pFile, "\n ; Собственно код...");
	fprintf(m_pFile, "\n");

	for (CTetradStream::iterator it = Tetrads.begin(); it != Tetrads.end(); ++it)
	{
		WriteTetrad(*it);
	}

	fprintf(m_pFile, "\n");
    fprintf(m_pFile, "\n RET");
    fprintf(m_pFile, "\n _asmentry ENDP");
    fprintf(m_pFile, "\n END");

	//fprintf(m_pFile, "\n mov AX, 4c00h");
	//fprintf(m_pFile, "\n int 21h");
	//fprintf(m_pFile, "\n");
	//fprintf(m_pFile, "\n main ENDP");
	//fprintf(m_pFile, "\n Code_Seg	ENDS");
	//fprintf(m_pFile, "\n END main");
}

//-----------------------------------------------------------------------------

void CGenAsm::WriteTetrad(STetrad &tet)
{
	char sBuff[256];
    std::string sLabel1, sLabel2, sLabel3;
	tet.Print(sBuff);
	fprintf(m_pFile, "\n");
	fprintf(m_pFile, "\n ; %s", sBuff);
	switch (tet.operation)
	{
        // Операции целочисленной арифметики -----------------
		case TET_OP_ADD:
			fprintf(m_pFile, "\n mov AX, word ptr %s", tet.operand1.c_str());
			fprintf(m_pFile, "\n add AX, word ptr %s", tet.operand2.c_str());
			fprintf(m_pFile, "\n mov word ptr %s, AX", tet.result.c_str());
		break;

		case TET_OP_SUBTRACT:
			fprintf(m_pFile, "\n mov AX, word ptr %s", tet.operand1.c_str());
			fprintf(m_pFile, "\n sub AX, word ptr %s", tet.operand2.c_str());
			fprintf(m_pFile, "\n mov word ptr %s, AX", tet.result.c_str());
		break;

        case TET_OP_MULT:
			fprintf(m_pFile, "\n mov AX, word ptr %s", tet.operand1.c_str());
			fprintf(m_pFile, "\n imul word ptr %s", tet.operand2.c_str());
			fprintf(m_pFile, "\n mov word ptr %s, AX", tet.result.c_str());
        break;

        case TET_OP_DIV:
            // В нашей реализации операций целочисленного деления быть не должно
            assert(false);
//    		fprintf(m_pFile, "\n mov AX, %s", tet.operand1.c_str());
//			fprintf(m_pFile, "\n sub AX, %s", tet.operand2.c_str());
//			fprintf(m_pFile, "\n mov %s, AX", tet.result.c_str());
        break;

        case TET_OP_UMINUS :
			fprintf(m_pFile, "\n mov AX, word ptr %s", tet.operand1.c_str());
			fprintf(m_pFile, "\n neg AX");
			fprintf(m_pFile, "\n mov word ptr %s, AX", tet.result.c_str());
        break;

        // Операции сравнения целых чисел --------------------
        case TET_OP_REL_E  :
        case TET_OP_REL_NE :
        case TET_OP_REL_G  :
        case TET_OP_REL_GE :
        case TET_OP_REL_L  :
        case TET_OP_REL_LE :

            sLabel1 = NewLabel();
            sLabel2 = NewLabel();

            fprintf(m_pFile, "\n mov AX, word ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n cmp AX, word ptr %s", tet.operand2.c_str());
            fprintf(m_pFile, "\n %s  %s", GetConditionInstruction(tet.operation), sLabel1.c_str());
            fprintf(m_pFile, "\n mov byte ptr %s, 0", tet.result.c_str());
            fprintf(m_pFile, "\n jmp %s", sLabel2.c_str());
            fprintf(m_pFile, "\n %s :", sLabel1.c_str());
            fprintf(m_pFile, "\n mov byte ptr %s, 1", tet.result.c_str());
            fprintf(m_pFile, "\n %s :", sLabel2.c_str());
        break;

        // Операции сравнения вещественных чисел --------------------
        case TET_OP_REL_E_F  :
        case TET_OP_REL_NE_F :
        case TET_OP_REL_G_F  :
        case TET_OP_REL_GE_F :
        case TET_OP_REL_L_F  :
        case TET_OP_REL_LE_F :
            sLabel1 = NewLabel();
            sLabel2 = NewLabel();

            fprintf(m_pFile, "\n fld dword ptr %s", tet.operand2.c_str());
            fprintf(m_pFile, "\n fld dword ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n fcompp");
            fprintf(m_pFile, "\n fstsw	ax");
            fprintf(m_pFile, "\n sahf");
            fprintf(m_pFile, "\n fwait");
            fprintf(m_pFile, "\n %s  %s", GetConditionInstruction(tet.operation), sLabel1.c_str());
            fprintf(m_pFile, "\n mov byte ptr %s, 0", tet.result.c_str());
            fprintf(m_pFile, "\n jmp %s", sLabel2.c_str());
            fprintf(m_pFile, "\n %s :", sLabel1.c_str());
            fprintf(m_pFile, "\n mov byte ptr %s, 1", tet.result.c_str());
            fprintf(m_pFile, "\n %s :", sLabel2.c_str());
        break;

        // Операция приведения целого к вещественному --------
        case TET_OP_ITOF :
            fprintf(m_pFile, "\n fild  word ptr %s",  tet.operand1.c_str());
            fprintf(m_pFile, "\n fstp  dword ptr %s", tet.result.c_str());
            fprintf(m_pFile, "\n fwait");
        break;

        // Операция приведения символа к строке --------------
        case TET_OP_CHAR_TO_STR:
            fprintf(m_pFile, "\n mov BP, offset %s"  , tet.result.c_str());
            fprintf(m_pFile, "\n mov AL, byte ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n mov [BP],   AL");
            fprintf(m_pFile, "\n mov [BP+1], 0");
        break;

        // Операции вещественной арифметики ------------------
        case TET_OP_ADD_F:
            fprintf(m_pFile, "\n fld  dword ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n fld  dword ptr %s", tet.operand2.c_str());
            fprintf(m_pFile, "\n fadd");
            fprintf(m_pFile, "\n fstp dword ptr %s", tet.result.c_str());
            fprintf(m_pFile, "\n fwait");
        break;

        case TET_OP_SUBTRACT_F:
            fprintf(m_pFile, "\n fld  dword ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n fld  dword ptr %s", tet.operand2.c_str());
            fprintf(m_pFile, "\n fsub");
            fprintf(m_pFile, "\n fstp dword ptr %s", tet.result.c_str());
            fprintf(m_pFile, "\n fwait");
        break;

        case TET_OP_MULT_F:
            fprintf(m_pFile, "\n fld  dword ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n fld  dword ptr %s", tet.operand2.c_str());
            fprintf(m_pFile, "\n fmul");
            fprintf(m_pFile, "\n fstp dword ptr %s", tet.result.c_str());
            fprintf(m_pFile, "\n fwait");
        break;

        case TET_OP_DIV_F:
            fprintf(m_pFile, "\n fld  dword ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n fld  dword ptr %s", tet.operand2.c_str());
            fprintf(m_pFile, "\n fdiv");
            fprintf(m_pFile, "\n fstp dword ptr %s", tet.result.c_str());
            fprintf(m_pFile, "\n fwait");
        break;

        case TET_OP_UMINUS_F:
            fprintf(m_pFile, "\n fld  dword ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n fchs");
            fprintf(m_pFile, "\n fstp dword ptr %s", tet.result.c_str());
        break;

        // Операции вывода -----------------------------------
        case TET_OP_WRITE_CHAR:
            fprintf(m_pFile, "\n xor  AX, AX");
            fprintf(m_pFile, "\n mov  AL, byte ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n push AX");
            fprintf(m_pFile, "\n call _write_char");
            fprintf(m_pFile, "\n add  sp, 2");
        break;

        case TET_OP_WRITE_INT:
            fprintf(m_pFile, "\n push word ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n call _write_int");
            fprintf(m_pFile, "\n add  sp, 2");
        break;

        case TET_OP_WRITE_REAL:
            fprintf(m_pFile, "\n push dword ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n call _write_flt");
            fprintf(m_pFile, "\n add  sp, 4");
        break;

        case TET_OP_WRITE_STR:
            fprintf(m_pFile, "\n push offset %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n call _write_str");
            fprintf(m_pFile, "\n add  sp, 2");
        break;

        case TET_OP_WRITELN:
            fprintf(m_pFile, "\n call _write_ln");
        break;

        // Операции вывода -----------------------------------

        case TET_OP_READ_CHAR:
            fprintf(m_pFile, "\n push offset %s", tet.result.c_str());
            fprintf(m_pFile, "\n call _read_char");
            fprintf(m_pFile, "\n add  sp, 2");
        break;

        case TET_OP_READ_INT:
            fprintf(m_pFile, "\n push offset %s", tet.result.c_str());
            fprintf(m_pFile, "\n call _read_int");
            fprintf(m_pFile, "\n add  sp, 2");
        break;

        case TET_OP_READ_REAL:
            fprintf(m_pFile, "\n push offset %s", tet.result.c_str());
            fprintf(m_pFile, "\n call _read_flt");
            fprintf(m_pFile, "\n add  sp, 2");
        break;

        case TET_OP_READ_STR:
            fprintf(m_pFile, "\n push offset %s", tet.result.c_str());
            fprintf(m_pFile, "\n call _read_str");
            fprintf(m_pFile, "\n add  sp, 2");
        break;

        // Операции присваивания -----------------------------
        case TET_OP_ASSIGN_INT:
            fprintf(m_pFile, "\n mov AX, word ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n mov word ptr %s, AX", tet.result.c_str());
        break;

        case TET_OP_ASSIGN_FP:
            fprintf(m_pFile, "\n fld   dword ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n fstp  dword ptr %s", tet.result.c_str());
            fprintf(m_pFile, "\n fwait");
        break;

        case TET_OP_ASSIGN_BOOL:    // размеры совпадают, так что совместим
        case TET_OP_ASSIGN_CH:
            fprintf(m_pFile, "\n mov AL, byte ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n mov byte ptr %s, AL", tet.result.c_str());
        break;

        case TET_OP_ASSIGN_STR:
            fprintf(m_pFile, "\n push offset %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n push offset %s", tet.result.c_str());
            fprintf(m_pFile, "\n call _copy_str");
            fprintf(m_pFile, "\n add  sp, 4");
        break;

        case TET_OP_ASSIGN_STACK:
            sLabel1 = NewLabel();
//            fprintf(m_pFile, "\n mov BP, offset %s", tet.operand1.c_str()); // присваиваемое
//            fprintf(m_pFile, "\n mov BX, offset %s", tet.result.c_str());   // результат
            fprintf(m_pFile, "\n mov CX, %d", STACK_SIZE_BYTES-1);
            fprintf(m_pFile, "\n mov SI, 0");
            fprintf(m_pFile, "\n %s :"          , sLabel1.c_str());
            fprintf(m_pFile, "\n mov AL, %s[SI]", tet.operand1.c_str());
            fprintf(m_pFile, "\n mov %s[SI], AL", tet.result.c_str());
            fprintf(m_pFile, "\n inc SI");
            fprintf(m_pFile, "\n loop %s"       , sLabel1.c_str());
        break;


        // Операции передачи управления ----------------------
        case TET_OP_DEF_LABEL : 
            fprintf(m_pFile, "\n %s :", tet.operand1.c_str());
            fprintf(m_pFile, "\n");
        break;

        case TET_OP_GOTO :
            fprintf(m_pFile, "\n jmp %s", tet.operand1.c_str());
        break;

        case TET_OP_GOTO_ZERO :
            // Операции семейства "jcc" позволяют прыгать только на -127..128 байт
            // что в данном случае может быть недостаточно
            // поэтому прыгать будет ближним безусловным переходом
            sLabel1 = NewLabel();
            fprintf(m_pFile, "\n mov AL, byte ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n cmp AL, 0");
            fprintf(m_pFile, "\n jne %s", sLabel1.c_str());
            fprintf(m_pFile, "\n jmp %s", tet.operand2.c_str());
            fprintf(m_pFile, "\n %s :"  , sLabel1.c_str());
        break;

        // Операция инкремента целого числа ------------------
        case TET_OP_INC_INT:
            fprintf(m_pFile, "\n inc word ptr %s", tet.operand1.c_str());
        break;

        // Логическое И --------------------------------------
        // Реализация почти идентична тому, что делает BC++ 3.1
        case TET_OP_AND:
            sLabel1 = NewLabel();   // переходим если FALSE
            sLabel2 = NewLabel();   // конец
            fprintf(m_pFile, "\n cmp byte ptr %s, 0", tet.operand1.c_str());
            fprintf(m_pFile, "\n je %s"             , sLabel1.c_str());
            fprintf(m_pFile, "\n cmp byte ptr %s, 0", tet.operand2.c_str());
            fprintf(m_pFile, "\n je %s"             , sLabel1.c_str());
            fprintf(m_pFile, "\n mov byte ptr %s, 1", tet.result.c_str());
            fprintf(m_pFile, "\n jmp %s"            , sLabel2.c_str());
            fprintf(m_pFile, "\n %s :"              , sLabel1.c_str());
            fprintf(m_pFile, "\n mov byte ptr %s, 0", tet.result.c_str());
            fprintf(m_pFile, "\n %s :"              , sLabel2.c_str());
        break;

        // Логическое ИЛИ ------------------------------------
        case TET_OP_OR:
            sLabel1 = NewLabel();
            sLabel2 = NewLabel();
            sLabel3 = NewLabel();
            fprintf(m_pFile, "\n cmp byte ptr %s, 0", tet.operand1.c_str());
            fprintf(m_pFile, "\n jne %s"            , sLabel1.c_str());
            fprintf(m_pFile, "\n cmp byte ptr %s, 0", tet.operand2.c_str());
            fprintf(m_pFile, "\n jne %s"            , sLabel1.c_str());
            fprintf(m_pFile, "\n mov byte ptr %s, 0", tet.result.c_str());
            fprintf(m_pFile, "\n jmp %s"            , sLabel2.c_str());
            fprintf(m_pFile, "\n %s :"              , sLabel1.c_str());
            fprintf(m_pFile, "\n mov byte ptr %s, 1", tet.result.c_str());
            fprintf(m_pFile, "\n %s :"              , sLabel2.c_str());
        break;

        // Логическое НЕ -------------------------------------
        // BC++ 3.1 делает нечто интересное... разбираться некогда, делаем втупую :)
        case TET_OP_NOT:
            sLabel1 = NewLabel();
            sLabel2 = NewLabel();
            fprintf(m_pFile, "\n cmp byte ptr %s, 0", tet.operand1.c_str());
            fprintf(m_pFile, "\n je %s"             , sLabel1.c_str());
            fprintf(m_pFile, "\n mov byte ptr %s, 0", tet.result.c_str());
            fprintf(m_pFile, "\n jmp %s"            , sLabel2.c_str());
            fprintf(m_pFile, "\n %s :"              , sLabel1.c_str());
            fprintf(m_pFile, "\n mov byte ptr %s, 1", tet.result.c_str());
            fprintf(m_pFile, "\n %s :"              , sLabel2.c_str());
        break;

        // Конкатенация строк --------------------------------
        case TET_OP_STR_CONCAT:
            fprintf(m_pFile, "\n push offset %s", tet.result.c_str());
            fprintf(m_pFile, "\n push offset %s", tet.operand2.c_str());
            fprintf(m_pFile, "\n push offset %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n call _concat_str");
            fprintf(m_pFile, "\n add  sp, 6");
        break;

        // Операции со стеком --------------------------------

        case TET_OP_STACK_PUSH:
            // количество байт в стеке лежит в первом байте
            fprintf(m_pFile, "\n xor AX, AX");
            fprintf(m_pFile, "\n mov AL, byte ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n mov SI, AX");
            fprintf(m_pFile, "\n inc SI");
            fprintf(m_pFile, "\n mov AL, byte ptr %s", tet.operand2.c_str());
            fprintf(m_pFile, "\n mov %s[SI], AL", tet.operand1.c_str());
            fprintf(m_pFile, "\n mov AX, SI");
            fprintf(m_pFile, "\n mov byte ptr %s, AL", tet.operand1.c_str());
        break;

        case TET_OP_STACK_TOP:
            fprintf(m_pFile, "\n xor AX, AX");
            fprintf(m_pFile, "\n mov AL, byte ptr %s", tet.operand1.c_str());
            fprintf(m_pFile, "\n mov SI, AX");
            fprintf(m_pFile, "\n mov AL, %s[SI]", tet.operand1.c_str());
            fprintf(m_pFile, "\n mov byte ptr %s, AL", tet.result.c_str());
        break;

        case TET_OP_STACK_POP:
            fprintf(m_pFile, "\n dec byte ptr %s", tet.operand1.c_str());;
        break;

        default:
            assert(false);
            fprintf(m_pFile, "\n ");
            fprintf(m_pFile, "\n !!!!!! Error: unknown tetrad !!!!!");
            fprintf(m_pFile, "\n ");
	}
    fprintf(m_pFile, "\n ");
}
Соседние файлы в папке Курсовая работа2