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

📄 generate_asm.c

📁 自己开发的c0文法编译器
💻 C
字号:
#include "world.h"


int now_fun=0;  //当前函数
struct midcode	*p,*node_current;  //中间代码中当前操作节点
FILE * fasm_out;
int funlast=0;  //上层函数




int tempnew_is(char *s)  //是否为中间变量
{
	if(s[0]=='#'&&strlen(s)>0)
		return 1;
	return 0;
}



void asmgenerate()
{
    
	int curpnum,currentpnum,curpnum1;
	int i;
	char ch ;
	int temp=0;
    int temp1=0;
	FILE *finout = fopen("stereotype.txt","r");  
	fasm_out = fopen("1.asm","w");//stack segment

	fprintf(fasm_out,"stack\tSegment\tstack\n");
	fprintf(fasm_out,"\tdw\t100 dup(?)\n");

	fprintf(fasm_out,"stack\tends\t\n\n");//stack segment end
	
	fprintf(fasm_out,"data\tSegment\n");//data segment
		fprintf(fasm_out,"str\tDB\t'WARNING :DIVIDE BY ZERO!',0AH,0DH,'$'\n");//除0报警
		if(print_num>0)  //定义字符串
	{
		for(i=0;i<print_num;i++)
			fprintf(fasm_out,"str%d	DB\t'%s',0AH,0DH,'$'\n",i,print_buf[i]);
	}
    

fprintf(fasm_out,"\tbufp\tdb\t0\n");
	fprintf(fasm_out,"\tbuflen\tdb\t255\n");
	fprintf(fasm_out,"\tactlen\tdb\t0\n");
	fprintf(fasm_out,"\tbuf\tdb\t255 DUP(13)\n");
	 p = mid;
	 while(p!=NULL&&now_fun==0&&strcmp(p->op,"Begin")!=0)
	 {
		 if(strcmp(p->op,"ConstDefine")==0)
		 {
			 fprintf(fasm_out,"\t%s\tdw\t%s\n",p->reg1,p->reg2);
		 }
		 else if(strcmp(p->op,"VarDefine")==0)
		 {
			fprintf(fasm_out,"\t%s\tdw\t?\n",p->reg1);
		 }
		 p = p->next;
	 }
	 fprintf(fasm_out,"data\tends\n\n");
	 
	 fprintf(fasm_out,"code\tSegment\tpara\n");
	 fprintf(fasm_out,"\tassume	cs:code,ds:data,ss:stack\n");
	 
	 while((ch=fgetc(finout))!=EOF)  //输入输出库
		 fputc(ch,fasm_out);
	 
	 while(p!=NULL)
	 {
		 while(p!=NULL&&strcmp(p->op,"Begin")==0)
		 {
			 funlast = now_fun;
			 now_fun = lookup_function(p->reg1);
			 if(strcmp(p->reg1,"main")==0)
			 {

				 fprintf(fasm_out,"%s\tproc\tfar\n",p->reg1);
				 fprintf(fasm_out,"\tMOV\tAX,\tdata\n");
				 fprintf(fasm_out,"\tMOV\tDS,\tAX\n");
                 
				 fprintf(fasm_out,"\tMOV\tAX,\tstack\n");
				 fprintf(fasm_out,"\tMOV\tSS,\tAX\n");

			}
			 else
			 {
				 fprintf(fasm_out,"%s\tproc\tnear\n",p->reg1);  //非main函数定义
				 
			 }
			 fprintf(fasm_out,"\tPUSH\tBP\n");
			 fprintf(fasm_out,"\tMOV\tBP,\tSP\n");
			 currentpnum = funTable[now_fun].paranum;
			 for(i=1;i<=currentpnum;i++)	fprintf(fasm_out,"\tPUSH\t[BP+%d]\n",2*(currentpnum+2-i));//传参数
	
			 p = p->next;
			 while(strcmp(p->op,"End")!=0)
			 {
				while(strcmp(p->op,"ConstDefine") == 0)
				{
					 fprintf(fasm_out,"\tMOV\tAX,\t%s\n",p->reg2);  //常量压栈
					 fprintf(fasm_out,"\tPUSH\tAX\n");
					 p = p ->next;
				}
				while(strcmp(p->op,"VarDefine") == 0)
				{
						fprintf(fasm_out,"\tPUSH\tAX\n");  //在栈中为变量分配空间
						p = p->next;
				}
				while(strcmp(p->op,"+") == 0 || strcmp(p->op,"-") ==0 ||strcmp(p->op,"/")==0 || strcmp(p->op,"*") == 0)
				{
					if(isnumber(p->reg1)==1)		fprintf(fasm_out,"\tMOV\tAX,\t%s\n",p->reg1);
					else if(tempnew_is(p->reg1) == 1)			fprintf(fasm_out,"\tPOP\tAX\n");  //中间变量pop到ax
					else
					{
						if((curpnum=lookforward(p->reg1,now_fun)) != -1)		fprintf(fasm_out,"\tMOV\tAX,\t[BP-%d]\n",2*curpnum+2);  //是上层函数的变量,所以要到栈中[BP-%d]去取
						
						else if((curpnum=lookforward(p->reg1,0)) != -1)		fprintf(fasm_out,"\tMOV\tAX,\t%s\n",p->reg1);  //是本层函数的变量
					}
					if(isnumber(p->reg2)==1)		fprintf(fasm_out,"\tMOV\tBX,\t%s\n",p->reg2);
					else if(tempnew_is(p->reg2) == 1)		fprintf(fasm_out,"\tPOP\tBX\n");
					else
					{
						if((curpnum = lookforward(p->reg2,now_fun)) != -1 )	fprintf(fasm_out,"\tMOV\tBX,\t[BP-%d]\n",2*curpnum+2);
						if((curpnum = lookforward(p->reg2,0)) != -1 )	fprintf(fasm_out,"\tMOV\tBX,\t%s\n",p->reg2);
					}

					if(strcmp(p->op,"+") == 0)		fprintf(fasm_out,"\tADD\tAX,\tBX\n");
					else if(strcmp(p->op,"-") == 0)		fprintf(fasm_out,"\tSUB\tAX,\tBX\n");
					else if	(strcmp(p->op,"*") == 0)		fprintf(fasm_out,"\tIMUL\tBX\n");
					else if (strcmp(p->op,"/") == 0)		
					{
						fprintf(fasm_out,"\tmov\tcx\t,0\n");
					fprintf(fasm_out,"\tcmp\tbx\t,cx\n");
					fprintf(fasm_out,"\tJZ\tLERR%d\n",div_num);
					fprintf(fasm_out,"\tXOR\tDX\t,DX\n");
					fprintf(fasm_out,"\tDIV\tBX\n");
					fprintf(fasm_out,"\tJMP\tDIVEND%d\n",div_num);
					fprintf(fasm_out,"LERR%d:",div_num);
					fprintf(fasm_out,"\tmov\tah\t,9\n");
					fprintf(fasm_out,"\tmov\tdx\t,offset str\n");//divide by zero!
					fprintf(fasm_out,"\tint\t21h\n");
					fprintf(fasm_out,"DIVEND%d:\n",div_num);
						div_num++;	

					
					}
					
                    //计算结果处理
					if(tempnew_is(p->res) == 1)		fprintf(fasm_out,"\tPUSH\tAX\n");
					else if((curpnum = lookforward(p->reg2,now_fun)) != -1 )	fprintf(fasm_out,"\tMOV\t[BP-%d]\tAX\n",2*curpnum+2);
					else if((curpnum = lookforward(p->reg2,now_fun)) != -1 )	fprintf(fasm_out,"\tMOV\t[%d]\tAX\t%s\n",p->reg2);
					else	fprintf(fasm_out,"\tPUSH\tAX\n");

					p = p->next;
				}
				if(strcmp(p->op,"=") == 0)
				{
					if(isnumber(p->reg1)==1)
					{
						fprintf(fasm_out,"\tMOV\tAX,\t%s\n",p->reg1);
						if(tempnew_is(p->res) == 1)		fprintf(fasm_out,"\tPUSH\tAX\n");
						else if((curpnum = lookforward(p->res,now_fun)) != -1 )	fprintf(fasm_out,"\tMOV\t[BP-%d],\tAX\n",2*curpnum+2);
						else if((curpnum = lookforward(p->res,0)) != -1 )	fprintf(fasm_out,"\tMOV\t%s,\tAX\n",p->res);
						else fprintf(fasm_out,"\tPUSH\tAX\n");
					}
					else if(tempnew_is(p->reg1) == 1)
					{
						if((curpnum = lookforward(p->res,now_fun)) != -1 )	fprintf(fasm_out,"\tPOP\t[BP-%d]\n",2*curpnum+2);
						else if((curpnum = lookforward(p->res,0)) != -1 )	fprintf(fasm_out,"\tPOP\t%s\n",p->res);
						else ;//为函数的参数
					}
					
					else if((curpnum = lookforward(p->reg1,now_fun))!=-1||(curpnum = lookforward(p->reg1,0))!=-1)
					{
						if ((curpnum = lookforward(p->reg1,now_fun))!=-1)fprintf(fasm_out,"\tMOV\tAX,\t[BP-%d]\n",2*curpnum+2);
						else if((curpnum = lookforward(p->reg1,0))!=-1)		fprintf(fasm_out,"\tMOV\tAX,\t%s\n",p->reg1);
						
						if((curpnum = lookforward(p->res,now_fun)) != -1 )	fprintf(fasm_out,"\tMOV\t[BP-%d],\tAX\n",2*curpnum+2);
						else if((curpnum = lookforward(p->res,0)) != -1 )	fprintf(fasm_out,"\tMOV\t%s,\tAX\n",p->res);
						else if(tempnew_is(p->res) == 1)		fprintf(fasm_out,"\tPUSH\tAX\n");
						else fprintf(fasm_out,"\tPUSH\tAX\n"); 
					}
					p = p->next;
				}
				if (strcmp(p->op,"value=")==0)  //给中间变量赋值
				{
					if(isnumber(p->reg1)==1) fprintf(fasm_out,"\tPUSH\t%s\n",p->reg1);
					else if((curpnum = lookforward(p->reg1,now_fun))!=-1) fprintf(fasm_out,"\tPUSH\t[BP-%d]\n",2*curpnum+2);
					else if((curpnum = lookforward(p->reg1,0)) != -1 )  fprintf(fasm_out,"\PUSH\t%s\n",p->reg1);
					else if(tempnew_is(p->reg1) == 1) ;
					
					p = p->next;

				}
				if(strcmp(p->op,"Return") == 0)
				{
					if(isnumber(p->reg1) == 1)	fprintf(fasm_out,"\tMOV\tDX,\t%s\n",p->reg1);
					else if(tempnew_is(p->reg1)==1) fprintf(fasm_out,"\tPOP\tDX\n");
					else if((curpnum = lookforward(p->reg1,now_fun))!=-1)	fprintf(fasm_out,"\tMOV\tDX,\t[BP-%d]\n",2*curpnum+2);
					else if((curpnum = lookforward(p->reg1,0))!=-1)	fprintf(fasm_out,"\tMOV\tDX,\t%s\n",p->reg1);
			
					p = p->next;
				}
				if(strcmp(p->op,"Read") == 0)
				{
					fprintf(fasm_out,"\tcall\tscanf_int\n");
					if((curpnum = lookforward(p->reg1,now_fun))!=-1)			fprintf(fasm_out,"\tMOV\t[BP-%d],\tAX\n",2*curpnum+2); //给栈中变量赋值
					else if((curpnum = lookforward(p->reg1,0))!=-1)			fprintf(fasm_out,"\tMOV\t%s,\tAX\n",p->reg1);
					p = p->next;
				}
				if(strcmp(p->op,"==") == 0 || strcmp(p->op,"!=") == 0 || strcmp(p->op,"<") == 0 || strcmp(p->op,"<=") == 0 ||
					strcmp(p->op,">") == 0 || strcmp(p->op,">=") == 0)
				{
					if(isnumber(p->reg1)==1)		fprintf(fasm_out,"\tMOV\tAX,\t%s\n",p->reg1);
					else if(tempnew_is(p->reg1) == 1)			fprintf(fasm_out,"\tPOP\tAX\n");
					else
					{
						if((curpnum=lookforward(p->reg1,now_fun)) != -1)		fprintf(fasm_out,"\tMOV\tAX,\t[BP-%d]\n",2*curpnum+2);
						
						else if((curpnum==lookforward(p->reg1,0)) != -1)		fprintf(fasm_out,"\tMOV\tAX,\t%s\n",p->reg1);
					}
					if(isnumber(p->reg2)==1)		fprintf(fasm_out,"\tMOV\tBX,\t%s\n",p->reg2);
					else if(tempnew_is(p->reg2) == 1)		fprintf(fasm_out,"\tPOP\tBX\n");
					else
					{
						if((curpnum = lookforward(p->reg2,now_fun)) != -1 )	fprintf(fasm_out,"\tMOV\tBX,\t[BP-%d]\n",2*curpnum+2);
						if((curpnum = lookforward(p->reg2,0)) != -1 )	fprintf(fasm_out,"\tMOV\tBX,\t%s\n",p->reg2);
					}
					fprintf(fasm_out,"\tCMP\tAX,\tBX\n");
					node_current = p;
					p = p->next;
					if(strcmp(node_current->op,"==")==0)	fprintf(fasm_out,"\tJNZ\t%s\n",p->res);
					else if(strcmp(node_current->op,"!=")==0)	fprintf(fasm_out,"\tJZ\t%s\n",p->res);
					else if(strcmp(node_current->op,"<")==0)	fprintf(fasm_out,"\tJNB\t%s\n",p->res);
					else if(strcmp(node_current->op,"<=")==0)	fprintf(fasm_out,"\tJNS\t%s\n",p->res);
					else if(strcmp(node_current->op,">")==0)	fprintf(fasm_out,"\tJB\t%s\n",p->res);
					else if(strcmp(node_current->op,">=")==0)	fprintf(fasm_out,"\tJS\t%s\n",p->res);	
					p = p->next;
				}
				if(strcmp(p->op,"Flag")==0){	fprintf(fasm_out,"%s:\n",p->reg1); p = p->next;}
				if(strcmp(p->op,"Goto")==0){	fprintf(fasm_out,"\tJMP\t%s\n",p->reg1);p = p->next;}
				if(strcmp(p->op,"Callvalue")==0){ fprintf(fasm_out,"\tCall\t%s\n",p->reg1);fprintf(fasm_out,"\tPUSH\tDX\n"); p = p->next;}
				if(strcmp(p->op,"Call")==0)	{fprintf(fasm_out,"\tCall\t%s\n",p->reg1); p = p->next;}
				if(strcmp(p->op,"Writestring")==0)	{	
					fprintf(fasm_out,"\tmov\tah\t,9\n");
					fprintf(fasm_out,"\tmov\tdx\t,offset str%d\n",temp1);
					
					fprintf(fasm_out,"\tint\t21h\n");
					temp1++;
					p=p->next;}
				if(strcmp(p->op,"Writenumber")==0)	{
				if(isnumber(p->reg1) == 1)	fprintf(fasm_out,"\tMOV\tAX,\t%s\n",p->reg1);
				else if(tempnew_is(p->reg1)==1) fprintf(fasm_out,"\tPOP\tAX\n");
				else if((curpnum = lookforward(p->reg1,now_fun))!=-1)	fprintf(fasm_out,"\tMOV\tAX,\t[BP-%d]\n",2*curpnum+2);
				else if((curpnum = lookforward(p->reg1,0))!=-1)	fprintf(fasm_out,"\tMOV\tAX,\t%s\n",p->reg1);
				fprintf(fasm_out,"\tcall\t printf_int\n");p = p->next;}
			 }
			fprintf(fasm_out,"\tMOV\tSP,\tBP\n");
			 fprintf(fasm_out,"\tPOP\tBP\n");
			 if(strcmp(funTable[now_fun].fname,"main")==0){fprintf(fasm_out,"\tMOV\tAX,\t4C00h\n");fprintf(fasm_out,"\tINT\t21h\n");}
			 else	fprintf(fasm_out,"\tRET\t%d\n",2*funTable[now_fun].paranum);
			 fprintf(fasm_out,"%s\tendp\n\n",funTable[now_fun].fname);
			 now_fun = funlast;
			 p = p->next;
		 }
	 }
	 fprintf(fasm_out,"code\tends\n");
	 fprintf(fasm_out,"\tEnd\tmain\n");
}

⌨️ 快捷键说明

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