⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 code.cpp

📁 一个c语言的编译器的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				emitCode("ADD EAX,EBX");
				break;
			case MINUS:
				emitCode("SUB EAX,EBX");
				break;
			case MUL:
				emitCode("IMUL EBX");
				break;
			case DIV:
                emitCode("CDQ");
				emitCode("IDIV EBX");
				break;
			}
			emitTemp(tempR);
			break;
		case RELOP:
            label = emitLabel();
            label2 = emitLabel();
			genCodePart(t->pChild[0], STACK);   //oprand1 save to stack
			genCodePart(t->pChild[1], EBX);     //oprand2 save to ac1
			emitCode("POP EAX");                //get oprand1
			emitCode("SUB EAX,EBX");            //do the comparation
			switch(t->tokenT)
			{
			case LT:
				emitOneOprand("JL",label);
				break;
			case LTEQ:
				emitOneOprand("JLE",label);
				break;
			case GT:
				emitOneOprand("JG",label);
				break;
			case GTEQ:
				emitOneOprand("JGE",label);
				break;
			case EQ:
				emitOneOprand("JE",label);
				break;
			case NEQ:
				emitOneOprand("JNE",label);
				break;
			}
			emitCode("MOV EAX,0");
			emitOneOprand("JMP", label2);
            emitLine(label+':');
		    emitCode("MOV EAX,1");  //if true, jump here
            emitLine(label2+':');

            //At this time
            //EAX=1 represents true, 0 represents false
			emitTemp(tempR);
			break;
		case STMT:
            label=emitLabel();
			switch(t->childkind.stmtK)
			{
			case IF_STMT:
                label2=emitLabel();
				emitComment("If statement start");
				genCodePart(t->pChild[0], EAX);     //condition expression
                emitCode("CMP EAX,0");
                emitOneOprand("JE", label);         //jump to else when false
				genCodePart(t->pChild[1], NONE);
				emitOneOprand("JMP", label2);       //jump to end
                emitLine(label+':');
				genCodePart(t->pChild[2], NONE);
                emitLine(label2+':');
				emitComment("If statement end");
				break;
			case WHILE_STMT:
                label2=emitLabel();
                emitLine(label2+':');
				emitComment("While statement start");
				genCodePart(t->pChild[0], EAX);     //condition expression
                emitCode("CMP EAX,0");
                emitOneOprand("JE", label);         //jump out
				genCodePart(t->pChild[1], NONE);
                emitOneOprand("JMP", label2);       //jump back for loop
                emitLine(label+':');
				emitComment("While statement end");
				break;
			case RETURN_STMT:
				emitComment("Return statement start");
				genCodePart(t->pChild[0], EAX);
                emitCode("MOV SP,BP");
				emitCode("POP BP");        //fp=ofp
				emitNoOprand("RET");        //return
				emitComment("Return statement end");
				break;
			}
			break;
		case REFER:
			emitComment(string("Reference of ")+t->name);
			s=st_lookup(t->name);
			i=s->nestlevel;
			genCodePart(t->pChild[0], EBX); //subsript

            //Ugly code here:(, once we find a arrayname without
            //any subcript, we need its address rather than its
            //value, so temporarily change the symbol attribute...
            if(s->symboltype==ARRAY_SYMBOL
                && t->pChild[0]==NULL)
            {
                s->symboltype = VAR_SYMBOL;
                emitRefer(s, 1);
                s->symboltype = ARRAY_SYMBOL;
            }
            else if(s->symboltype==ARRAYADDR_SYMBOL &&
                t->pChild[0]==NULL)
            {
                s->symboltype = VAR_SYMBOL;
                emitRefer(s, 0);
                s->symboltype = ARRAYADDR_SYMBOL;
            }
            else
                emitRefer(s, 0);
			emitTemp(tempR);
            break;
        case CALL:
            emitComment(string("Call ")+t->name);
            
            //Reverse the argument order first
            //We'd like to push the args in
            //reverse order
            s=st_lookup(t->name);
            ttemp=t->pChild[0];
            while(ttemp!=NULL){
                if(ttemp->pNext==NULL)
                    break;
                ttemp=ttemp->pNext;
            }
            t->pChild[0]=ttemp;
            while(ttemp!=NULL)
            {
                ttemp->pNext=ttemp->pPrev;
                ttemp=ttemp->pPrev;
            }
            
            //Just pass the head of the arg-list
            //left ones will be dealt by genCodePart(t->pNext,tempR)
            genCodePart(t->pChild[0], STACK);
            emitOneOprand("CALL", '_'+t->name);
            if(s->paramAlloc > 0){  // eliminates all paramters
                os<<s->paramAlloc;
                emitTwoOprand("ADD", regs[SP], os.str());
                os.str()="";
            }
            emitTemp(tempR);
            break;
		case EXP:
			switch(t->childkind.expK)
			{
			case ASSIGN_EXP:
				emitComment("Assignment start: "+t->name);
				s=st_lookup(t->name);
				genCodePart(t->pChild[1], ECX); //value to assign=>ECX
				genCodePart(t->pChild[0], EBX); //subscript=>EBX
                emitRefer(s, 1);                //the address to EAX
                emitCode("MOV [EAX],ECX");      //do the assignment
                emitCode("MOV EAX,ECX");        //the value of this assignment-exp
				emitTemp(tempR);
				break;
			}
			break;
		case NUM:
			emitComment("Literal number: "+t->name);
			emitTwoOprand("MOV", regs[EAX],
                t->name);
			emitTemp(tempR);
			break;	
		}
		genCodePart(t->pNext,tempR);
	}
}

// Generate the global data declarations
void genDataPart(TreeNode *t)
{
	TreeNode *ttemp;
    emitLine("_DATA_SEG SEGMENT PUBLIC");
    while(t!=NULL){
		// Continuous variable declaration
        if(t->kind==DECLAR&&t->childkind.declarK==VAR_DECLAR_LIST){
			ttemp = t->pChild[0];
			while(ttemp!=NULL) {
				switch(ttemp->childkind.declarK){
				case VAR_DECLAR:
					emitDeclare(ttemp->name, 1);
					break;
				case ARRAY_DECLAR:
					emitDeclare(ttemp->name, ttemp->arraynum);
					break;
				}
				ttemp = ttemp->pNext;
			}
        }
        t = t->pNext;
    }
    emitLine("_DATA_SEG ENDS");
}

// Generate the initialization code for global data declarations
//
// And no worry about regeneration when call genCodePart with
// the whole grammar tree later, I've delt with it
void genGlobalInitPart(TreeNode *t)
{
	TreeNode *ttemp;
    emitComment("Global initialization starts");
    while(t!=NULL){
        if(t->kind==DECLAR){
            switch(t->childkind.declarK){
            case VAR_DECLAR_LIST:
				ttemp = t->pChild[0];
				while(ttemp!=NULL) {
					genCodePart(ttemp->pChild[0], NONE);
					ttemp->pChild[0] = NULL;	//Avoid code regeneration
					ttemp = ttemp->pNext;
				}
                break;
            }
        }
        t = t->pNext;
    }
    emitComment("Global initialization ends");
}

// Find function declarations without definition
// And generate 'EXTRN' declaration for them
void genExternSymbol()
{
    int i, n=0;
    string externDeclare="EXTRN ";
    for(i=0;i<BUCKET_SIZE;i++) {
        SymbolRecord *sr = GlobalBucket.pRecord[i];
        while(sr!=NULL) {
            // No definition?
            if(sr->symboltype==FUNC_DECLAR_SYMBOL) {
                externDeclare+='_';
                externDeclare+=sr->name;
                externDeclare+=":NEAR,";
                n++;
            }
            sr = sr->pNext;
        }
    }
    if(n>0) {
        externDeclare.at(externDeclare.length()-1)=' ';
        emitLine(externDeclare);
    }
}
void genCode(TreeNode *t)
{
	/* This check can be ignored, for the link of assembler
       will check this out:)
    SymbolRecord *s=st_lookup(string("main"));
	if(s==NULL)
		GenError("Entrypoint 'main' not found");
    */
    emitLine(".386");
    genDataPart(t);
    emitLine("_CODE_SEG SEGMENT USE16 PUBLIC");
    emitLine("ASSUME CS:_CODE_SEG,DS:_DATA_SEG");
    genExternSymbol();
    emitLine("START:");
	emitTwoOprand("XOR", "EBP", "EBP");
    emitTwoOprand("MOV", "AX", "_DATA_SEG");
    emitTwoOprand("MOV", regs[DS], "AX");
    emitTwoOprand("MOV", regs[ES], "AX");
	genGlobalInitPart(t);
    emitOneOprand("CALL", "_main");
    emitTwoOprand("MOV", "AX", "4C00H");    //Terminate the program
    emitOneOprand("INT","21H");
	genCodePart(t, NONE);
    emitLine("_CODE_SEG ENDS");
    emitLine("END START");  //Entry point
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -