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

📄 asm.c

📁 北京航空航天大学计算机系要求的编译器大作业。大概6000行代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************
By BHU 35060122 Peng Hui;
2008.02
description:
A small compiler to translate a C program to 80X80 Assembly Code
***************************************/


#include"Global.h"


void toAsm()
{
	MCode *mt,*mtt;
	char function[20];
	char str[20];
	char mylbl[20];
	AddTable *h1 = NULL,*h2 = NULL,*h3=NULL,*tp1,*hc1,*hc2;
	AddTable  *read;
	int counter = 1;
	int i = 0;
	int nparam = 0;
	int x = 0;
	int rp = 0;
	int push = 0;
	int retFlag = 0;
	
	
	asm = fopen("myfiles/out.asm","w");

	fprintf(asm,";By 35060122 Peng Hui\n");
	fprintf(asm,";2008  02 \n");
	fprintf(asm,";80X86 Assembly Code\n\n\n\n\n\n");
	fprintf(asm,".386\n.MODEL FLAT\n\nExitProcess	PROTO	NEAR32	stdcall,dwExitCode:DWORD\n\nINCLUDE	io.h\n\ncr	equ	0dh\nLf	equ	0ah\n"); // 生成一些必要的东西
	
	
	mt = head;         			// 中间代码的链表头。
	

	fprintf(asm,"\n.STACK\t4096\n\n\n");  // 这里是堆栈
	
	
	fprintf(asm,"\n.DATA\n");
	fprintf(asm,"_string	byte	10 dup(?),0\n");  // 专门用来读入数据的
	fprintf(asm,"lab	byte	11 dup(?), 0");
	
	
	while(strcmp(mt->op,"func") != 0)                         // h3是用来放全局常量、变量的
	{
		fprintf(asm,"%s\tDWORD\t%s\n",mt->ad1,mt->ad2);
	//	mt = mt->next;
		tp1 = (AddTable*)malloc(sizeof(AddTable));
		strcpy(tp1->id,mt->ad1);
		tp1->add = 0;
		tp1->next = NULL;
		
		if(h3 == NULL)
		{
			h3 = tp1;
			hc1 = tp1;
		}
		else
		{
			hc1->next = tp1;
			hc1 = hc1->next;
		}
		mt = mt->next;
	}
	
	
	fprintf(asm,"\n\n\n\n\n");
	fprintf(asm,";--------Code Segment-----------\n\n");
	fprintf(asm,".CODE\n\n");
	
	
	while(mt != NULL) // 这里专门用来处理子函数
	{
		//标号
		if(strcmp(mt->label,"") != 0 && strcmp(mt->label,"start") != 0)
			fprintf(asm,"%s:\n",mt->label);
		
		else if(strcmp(mt->op,"func") == 0 && strcmp(mt->ad1,"main") != 0)  // 一般子函数
		{
			counter = 0;

			rp = 0;								// 找出这个函数的形参个数。
			mtt = mt->next;

			while(strcmp(mtt->op,"vp") == 0)
			{
				rp++;
				mtt = mtt->next;
			}
			fprintf(asm,"%s\tproc\tNEAR32\n",mt->ad1);
			strcpy(function,mt->ad1);
			
			
			fprintf(asm,"\tpush\tebx\n");                // 保护现场
			fprintf(asm,"\tpush\tecx\n");
			fprintf(asm,"\tpush\tedx\n");
			fprintf(asm,"\tpush\tesi\n");
			fprintf(asm,"\tpush\tedi\n");
			fprintf(asm,"\tpushf\n");
			fprintf(asm,"\tpush\tebp\n");		// push	ebp

			fprintf(asm,"\tmov\tebp,\tesp\n");  // mov	ebp,	esp  BP指向当前函数的基地址

			fprintf(asm,"\n\n;-------------保护现场-------------\n\n");
			// 然后是把传入的值和局部变量再建一个表:变量名<-->地址(相对)
			// 以后如果有临时变量进来,如果需要的话,就压栈,建表。
			
			
		}	
		
		else if(strcmp(mt->op,"func") == 0 && strcmp(mt->ad1,"main") == 0)   // the main function 
		{
			fprintf(asm,"_start:\n");
			fprintf(asm,"\tpush\tebp\n");
			fprintf(asm,"\tmov\tebp,\tesp\n");
			strcpy(function,"main");
			counter = 0;
		}
			
		else if(strcmp(mt->op,"end") == 0  && strcmp(function,"main") != 0)
		{
			fprintf(asm,"\tadd\tesp,\t%d\n",4*counter);
			popReg();						 	// 退出寄存器
			
			fprintf(asm,"\tret\n");
			counter = 0;						// 函数结束,置计数器为0
			
			Destroy(h1);
			h1 = NULL;
			Destroy(h2);
			h2 = NULL;
		}
		
		else if(strcmp(mt->op,"end") == 0  && strcmp(function,"main") == 0)
		{
			fprintf(asm,"\tpop\tebp\n");
			fprintf(asm,"	INVOKE	ExitProcess,	0	;exit with code 0\n");
			fprintf(asm,"PUBLIC	_start\n");
			h1 = NULL;
			h2 = NULL;
			
			counter = 0;
			
		}
		
		else if(strcmp(mt->op,"pv") == 0)		// 传值  push vparameter,这里如何填写内存,要好好把握。
		{
			push ++;
			read = search(h1,mt->ad1);			// 查表要遵循一定的原则。先到本层里面找,再去上层找。
			if(read == NULL)                    // 去上层找,当然肯定能找到的,不然在语义分析中就会报错了。
			{
				read = search(h2,mt->ad1);
				if(read == NULL)                // 为了保证代码的安全。只能这样写了。
				{
					fprintf(asm,"\tmov\teax,\t%s\n",mt->ad1);
					fprintf(asm,"\t;to pass values to the function\n");
					fprintf(asm,"\tpush\teax\n");
				}
				else
				{
					fprintf(asm,"\tmov\teax,\t[ebp+(%d)]\n",read->add);
					fprintf(asm,"\t;to pass values to the function\n");
					fprintf(asm,"\tpush\teax\n");
				}
			}
			else
			{
				fprintf(asm,"\tmov\teax,\t[ebp+(%d)]\n",read->add);
				fprintf(asm,"\t;to pass values to the function\n");
				fprintf(asm,"\tpush\teax\n");
			}
		}
		
		else if(strcmp(mt->op,"const") == 0 || strcmp(mt->op,"var") == 0)// 局部变量和常量
		{
			tp1 = (AddTable*)malloc(sizeof(AddTable));
			tp1->add = (-1)*4*(++counter);
			tp1->next = NULL;
			strcpy(tp1->id,mt->ad1);
			fprintf(asm,"\tmov\teax,\t%s;Define Local Variables\n",mt->ad2);
			fprintf(asm,"\tpush\teax\n");
			if(h1 == NULL)                                                // 建立局部符号表。
			{
				h1 = tp1;
				hc1 = tp1;
			}
			else
			{
				hc1->next = tp1;
				hc1 = hc1->next;
			}
		}
		
		else if(strcmp(mt->op,"vp") == 0) // 列出函数的形参
		{
			tp1 = (AddTable*)malloc(sizeof(AddTable));              
			tp1->add = 4 * (6 + rp--)+2;
			tp1->next = NULL;
			strcpy(tp1->id,mt->ad1);							

			if(h1 == NULL)
			{
				h1  = tp1;
				hc1 = tp1;
			}
			else
			{
				hc1->next = tp1;
				hc1 = hc1->next;
			}
		}
		
		else if(strcmp(mt->op,"add") == 0 || strcmp(mt->op,"sub") == 0 || strcmp(mt->op,"mul") == 0 || strcmp(mt->op,"div") == 0) // + - * /
		{
			// 第二个参数。
			read = search(h1,mt->ad2);
			if(read == NULL)
			{
				read = search(h2,mt->ad2);
				if(read == NULL)
				{
				//	read = search(h3,mt->ad2);
				//	if(read )
					fprintf(asm,"\tmov\teax,\t%s\n",mt->ad2);
				}
				else
				{
					fprintf(asm,"\tmov\teax,\t[ebp+(%d)]\n",read->add);
				}
			}
			else
			{
				fprintf(asm,"\tmov\teax,\t[ebp+(%d)]\n",read->add);
			}
			
			fprintf(asm,"\tmov\tebx,\teax\n");
			
			// The first argument
			read = search(h1,mt->ad1);
			if(read == NULL)
			{
				read = search(h2,mt->ad1);
				if(read == NULL)
				{
					fprintf(asm,"\tmov\teax,\t%s\n",mt->ad1);
				}
				else
				{
					fprintf(asm,"\tmov\teax,\t[ebp+(%d)]\n",read->add);
				}
			}
			else
			{
				fprintf(asm,"\tmov\teax,\t[ebp+(%d)]\n",read->add);
			}

			// deal with the operand
			if(strcmp(mt->op,"add") == 0 || strcmp(mt->op,"sub") == 0)
			{
				fprintf(asm,"\t%s\teax,\tebx\n",mt->op);
			}
			else
			{
				fprintf(asm,"\t%s\tebx\n",mt->op);
			}
			
			// the third argument.
			
			read = search(h1,mt->ad3);
			if(read == NULL)
			{
				read = search(h2,mt->ad3);
				if(read == NULL)
				{
					read = search(h3,mt->ad3);
					if(read == NULL)   // then we have to new a transient Variable
					{
						tp1 = (AddTable *)malloc(sizeof(AddTable));
						strcpy(tp1->id,mt->ad3);
						tp1->add = (-4)*(++counter) ;
						tp1->next = NULL;
						
						if(h2 == NULL)
						{
							h2 = tp1;
							hc2 = tp1;
						}
						else
						{
							hc2->next = tp1;
							hc2 = hc2->next;
						}
						
						fprintf(asm,"\tpush\teax\n");
					}
					else				// ok,global variable
					{
						fprintf(asm,"\tmov\t%s\teax\n",mt->ad3);
					}
				}
				else
				{
					fprintf(asm,"\tmov\t[ebp+(%d)],eax\n",read->add);
				}
			}
			else
			{
				fprintf(asm,"\tmov\t[ebp+(%d)],eax\n",read->add);
			}
		}
		
		
		else if(strcmp(mt->op,"read") == 0) // the read sb statement
		{
			read = search(h1,mt->ad1);  
			if(read == NULL)
			{
				read = search(h2,mt->ad1);
				if(read == NULL)
				{
					fprintf(asm,"\tinput	_string,	10\n");
					fprintf(asm,"\tatod 	_string\n");
					fprintf(asm,"\tmov\t%s,\teax\n",mt->ad1);
				}
				else
				{
					fprintf(asm,"\tinput	_string,	10\n");
					fprintf(asm,"\tatod	_string\n");
					fprintf(asm,"\tmov\t[ebp+(%d)],\teax\n",read->add);
				}
			}
			else  // 局部变量
			{
				fprintf(asm,"\tinput	_string,	10\n");
				fprintf(asm,"\tatod	    _string\n");
				fprintf(asm,"\tmov\t[ebp+(%d)],\teax\n",read->add);
			}
		}
		
		else if(strcmp(mt->op,"write") == 0)  // the write statement
		{
			if(strcmp(mt->ad2,"string") == 0)  
			{

⌨️ 快捷键说明

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