📄 asm.c
字号:
/***************************************
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 + -