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

📄 x86linux.c

📁 浙江大学编译原理课程设计源代码,高等院校计算机专业
💻 C
📖 第 1 页 / 共 4 页
字号:
#define  X86_LINUX#include  <stdio.h>#include  "common.h"#include  "symtab.h"#include  "error.h"#include  "x86.h"#ifdef _MSDOS_#include  <dos.h>#elif defined __linux__#include <time.h>#endif#include  _YTAB_H_#define  MAX_LOOP_LEVEL  16#define  STMT_STACK_SIZE 64#define  MAX_CALL_LEVEL 16static symtab *rtn =NULL;static symbol *arg = NULL;static Symbol	p;static Symtab	ptab;static void emit_linux_write1(int arg_type);static void emit_linux_sqrt(int arg_type);static void emit_linux_odd(int arg_type);static void emit_linux_abs(int arg_type);static void emit_linux_sqr(int arg_type);static void emit_linux_read1(int arg_type);static void emit_linux_writeln(int arg_type);static int gen_level = 0;static void emit_linux_program_head();static void emit_linux_program_prologue(symtab *);static void emit_linux_program_epilogue(symtab *);static void emit_linux_main_prologue(symtab *);static void emit_linux_main_epilogue(symtab *);static void emit_linux_routine_prologue(symtab *);static void emit_linux_routine_epilogue(symtab *);static void emit_linux_local_args(symtab *);static void emit_linux_dos_push_op(Type ptype);static void emit_linux_load_value(symbol *);static void do_linux_function_assign(symtab *,int);static void do_linux_procedure_call(symtab *);static void do_linux_assign(symbol *, int);static void do_linux_expression(Type, int);static void do_linux_negate(symbol *);static void do_linux_expr(Type, int);static void do_linux_term(Type, int);static void do_linux_factor(symbol *);static void do_linux_array_factor(symbol *);static void do_linux_record_factor(symbol *, symbol *);static void do_linux_first_arg(int);static int emit_linux_address = 0;extern char datname[FILE_NAME_LEN];#ifdef LABEL_RETVAL#undef LABEL_RETVAL#define LABEL_RETVAL "-4(%ebp)"#endif#ifdef LABEL_SLINK#undef LABEL_SLINK#define LABEL_SLINK	"8(%ebp)"#endifstatic void do_linux_sys_routine(int routine_id, int arg_type){    switch(routine_id)    {    case fABS:        emit_linux_abs(arg_type);        break;    case fODD:        emit_linux_odd(arg_type);        break;    case  fPRED:        fprintf(codfp, "\t\tdecl\t%%eax\n");        break;    case  fSQR:        emit_linux_sqr(arg_type);        break;    case fSQRT:        emit_linux_sqrt(arg_type);        break;    case fSUCC:        fprintf(codfp, "\t\tincl\t%%eax\n");        break;    case pREAD:        emit_linux_read1(arg_type);        break;    case pREADLN:        emit_linux_read1(arg_type);        break;    case pWRITE:        emit_linux_write1(arg_type);        break;    case  pWRITELN:        emit_linux_writeln(arg_type);        break;    default:        break;    }}static void emit_linux_read1(int arg_type){    fprintf(codfp, "\t\tpushl\t%%eax\n");    fprintf(codfp, "\t\tpushl\t%%ebp\n");    switch(arg_type)    {    case  TYPE_REAL:        break;    case  TYPE_INTEGER:        fprintf(codfp, "\t\tcall\t_read_int\n");        break;    case TYPE_STRING:        fprintf(codfp, "\t\tcall\t_read_string\n");        break;    case TYPE_CHAR:        fprintf(codfp, "\t\tcall\t_read_char\n");        break;    case   TYPE_BOOLEAN:    default:        parse_error("operand type do not match operator.", "");        break;    }	fprintf(codfp, "\t\taddl\t$8, %%esp\n");}static void emit_linux_write1(int arg_type){    switch(arg_type)    {    case TYPE_BOOLEAN:    case TYPE_INTEGER:        fprintf(codfp, "\t\tpushl\t%%eax\n");        fprintf(codfp, "\t\tpushl\t%%ebp\n");        fprintf(codfp, "\t\tcall\t_write_int\n");        break;    case TYPE_CHAR:        fprintf(codfp, "\t\tpushl\t%%eax\n");        fprintf(codfp, "\t\tpushl\t%%ebp\n");        fprintf(codfp, "\t\tcall\t_write_char\n");        break;    case TYPE_STRING:        fprintf(codfp, "\t\tpushl\t%%eax\n");        fprintf(codfp, "\t\tpushl\t%%ebp\n");        fprintf(codfp, "\t\tcall\t_write_string\n");        break;    default:        break;    }	fprintf(codfp, "\t\taddl\t$8, %%esp\n");}static void emit_linux_writeln(int arg_type){    switch(arg_type)    {    case TYPE_BOOLEAN:    case TYPE_INTEGER:        fprintf(codfp, "\t\tpushl\t%%eax\n");        fprintf(codfp, "\t\tpushl\t%%ebp\n");        fprintf(codfp, "\t\tcall\t_writeln_int\n");        break;    case TYPE_CHAR:        fprintf(codfp, "\t\tpushl\t%%eax\n");        fprintf(codfp, "\t\tpushl\t%%ebp\n");        fprintf(codfp, "\t\tcall\t_writeln_char\n");        break;    case  TYPE_STRING:        fprintf(codfp, "\t\tpushl\t%%eax\n");        fprintf(codfp, "\t\tpushl\t%%ebp\n");        fprintf(codfp, "\t\tcall\t_writeln_string\n");        break;    default:        break;    }	fprintf(codfp, "\t\taddl\t$8, %%esp\n");}static void emit_linux_abs(int arg_type){    fprintf(codfp, "\t\tpushl\t%%ebp\n");    switch(arg_type)    {    case TYPE_BOOLEAN:    case TYPE_INTEGER:        fprintf(codfp, "\t\tcall\t_abs_int\n");        break;    case TYPE_CHAR:        fprintf(codfp, "\t\txorb\t%%ah,%%ah\n");        fprintf(codfp, "\t\tcall\t_abs_int\n");        break;    default:        break;    }	fprintf(codfp, "\t\taddl\t$8, %%esp\n");}static void emit_linux_sqr(int arg_type){    fprintf(codfp, "\t\tpushl\t%%bp\n");    switch(arg_type)    {    case TYPE_BOOLEAN:    case TYPE_INTEGER:        fprintf(codfp, "\t\tcall\t_sqr_int\n");        break;    case TYPE_CHAR:        fprintf(codfp, "\t\txorb\t%%ah,%%ah\n");        fprintf(codfp, "\t\tcall\t_sqr_int\n");        break;    default:        break;    }	fprintf(codfp, "\t\taddl\t$8, %%esp\n");}static void emit_linux_odd(int arg_type){    fprintf(codfp, "\t\tpushl\t%%bp\n");    switch(arg_type)    {    case TYPE_BOOLEAN:    case TYPE_INTEGER:        fprintf(codfp, "\t\tcall\t_odd_int\n");        break;    case TYPE_CHAR:        fprintf(codfp, "\t\txorb\t%%ah,%%ah\n");        fprintf(codfp, "\t\tcall\t_odd_int\n");        break;    default:        break;    }	fprintf(codfp, "\t\taddl\t$8, %%esp\n");}static void emit_linux_sqrt(int arg_type){    fprintf(codfp, "\t\tpushl\t%%ebp\n");    switch(arg_type)    {    case TYPE_BOOLEAN:    case TYPE_INTEGER:        fprintf(codfp, "\t\tcall\t_sqrt_int\n");        break;    case TYPE_CHAR:        fprintf(codfp, "\t\txorb\t%%ah,%%ah\n");        fprintf(codfp, "\t\tcall\t_sqrt_int\n");        break;    default:        break;    }	fprintf(codfp, "\t\taddl\t$8, %%esp\n");}static void emit_linux_program_prologue(symtab *ptab){    fprintf(codfp,"\n\n#---program %s ---",ptab->name);    emit_linux_program_head();}/* char datname[]; */static void emit_linux_program_head(){    fprintf(datfp, "#\n");    fprintf(datfp, "#SPL Compiler Ver %s\n",_PC_VER_);    fprintf(datfp, "#\n");    fprintf(datfp, ".file \"%s\"\n\n", datname);	fprintf(datfp, "sys_call_id = 0x80\n");	fprintf(datfp, "exit_syscall = 0x1\n\n");}static void emit_linux_program_epilogue(symtab *ptab){    symbol *p;	fprintf(codfp, "\n\n.globl _start\n");	fprintf(codfp, "_start:\n");	fprintf(codfp, "\t\tcall _main\n");	fprintf(codfp, "\t\tmovl $0, %%ebx\n");	fprintf(codfp, "\t\tmovl $exit_syscall, %%eax\n");	fprintf(codfp, "\t\tint  $sys_call_id\n");	fprintf(codfp, ".ident	\"SPL: 0.1.5\"\n");    fprintf(codfp, "\n#.bss variables\n");    for(p = ptab->locals; p; p = p->next)    {        if (p->defn != DEF_CONST)        {				switch (p->type->type_id)				{				case 	TYPE_CHAR:					fprintf(codfp, "\t\t.comm %s,%d,%d\n", p->rname, IR->charmetric.size, IR->intmetric.align);					break;				case	TYPE_BOOLEAN:				case 	TYPE_INTEGER:					fprintf(codfp, "\t\t.comm %s,%d,%d\n", p->rname, IR->intmetric.size, IR->intmetric.align);					break;				case 	TYPE_REAL:					break;				case 	TYPE_STRING:					break;				case TYPE_ARRAY:					if(p->type_link->last->type->type_id == TYPE_INTEGER							|| p->type_link->last->type->type_id == TYPE_BOOLEAN)							/*						fprintf(datfp,"%s\t\tdw\t0%xh dup (?)\n"								,p->rname,p->type_link->num_ele);								*/						fprintf(codfp,"\t\t.comm %s, %d, %d\n"								,p->rname, p->type_link->num_ele * IR->intmetric.size, 								IR->intmetric.align);					else if(p->type_link->last->type->type_id ==							TYPE_CHAR)							/*						fprintf(datfp,"%s\t\tdb\t0%xh dup (?)\n"								,p->rname,p->type_link->num_ele);								*/						fprintf(codfp,"\t\t.comm %s, %d, %d\n"								,p->rname,p->type_link->num_ele,								IR->intmetric.align);					else						parse_error("complex array element not supported","");					if(p->defn != DEF_CONST)						continue;					break;				case   TYPE_RECORD:					/*					fprintf(datfp,"%s\t\tdb\t0%xh dup (?)\n"							,p->rname,p->type_link->size);							*/					fprintf(codfp,"\t\t.comm %s, %d, %d\n"							,p->rname, p->type_link->size,							IR->intmetric.align);					continue;				default:					break;				}		}    }	/* global variable as .data */	fprintf(datfp, ".data\n");    for(p = ptab->locals; p; p = p->next)    {        if (p->defn == DEF_CONST)        {				switch (p->type->type_id)				{				case 	TYPE_CHAR:					fprintf(datfp, ".globl %s\n", p->rname);					/* fprintf(datfp, "\t\t.align %d\n", IR->charmetric.align); */					fprintf(datfp, "\t\t.type %s @object\n", p->rname);					fprintf(datfp, "\t\t.size %s, %d\n", p->rname, IR->charmetric.size);					fprintf(datfp, "%s:\n", p->rname);					fprintf(datfp, "\t\t.byte %d\n", p->v.c);					break;				case	TYPE_BOOLEAN:				case 	TYPE_INTEGER:					fprintf(datfp, ".globl %s\n", p->rname);					fprintf(datfp, "\t\t.align %d\n", IR->intmetric.align);					fprintf(datfp, "\t\t.type %s @object\n", p->rname);					fprintf(datfp, "\t\t.size %s, %d\n", p->rname, IR->intmetric.size);					fprintf(datfp, "%s:\n", p->rname);					fprintf(datfp, "\t\t.long %d\n", p->v.i);					break;				case 	TYPE_REAL:					break;				case 	TYPE_STRING:					fprintf(datfp, ".globl %s\n", p->rname);					fprintf(datfp, "\t\t.section .rodata\n");					fprintf(datfp, "\t\t.align %d\n", IR->pointermetric.align);					fprintf(datfp, ".LC%s:\n", p->rname);					if ((p->v.s[0] == '\'') && (p->v.s[strlen(p->v.s) - 1] == '\''))					{						p->v.s[strlen(p->v.s) - 1] = '\0';						fprintf(datfp, "\t\t.string \"%s\"\n", p->v.s + 1);					}					else						fprintf(datfp, "\t\t.string \"%s\"\n", p->v.s);					fprintf(datfp, "\t\t.data\n");					fprintf(datfp, "\t\t.align %d\n", IR->pointermetric.align);					fprintf(datfp, "\t\t.type %s @object\n", p->rname);					fprintf(datfp, "\t\t.size %s, %d\n", p->rname, IR->pointermetric.size);					fprintf(datfp, "%s:\n", p->rname);					fprintf(datfp, "\t\t.long .LC%s\n", p->rname);					break;				case TYPE_ARRAY:					break;				case TYPE_RECORD:					break;				default:					break;				}		}    }}static void emit_linux_main_prologue(symtab *ptab){    fprintf(codfp,"\n\n# --- main routine ----\n");	fprintf(codfp, "\t\t.text\n");	fprintf(codfp, ".globl _main\n");	fprintf(codfp, "\t\t.type _main, @function\n");	fprintf(codfp, "_main:\n");	fprintf(codfp, "\t\tpushl\t%%ebp\n");	fprintf(codfp, "\t\tmovl\t%%esp, %%ebp\n");}static void emit_linux_main_epilogue(symtab *ptab){	fprintf(codfp,"\t\tleave\n");    fprintf(codfp,"\t\tret\n");	fprintf(codfp,".size _main, .-main\n");}static void emit_linux_routine_prologue(symtab *ptab){    if(ptab->defn == DEF_PROG)        return;    fprintf(codfp,"\n\n# routine : %s \n",ptab->name);    emit_linux_local_args(ptab);	fprintf(codfp, "\t\t.text\n");	fprintf(codfp, ".globl %s\n", ptab->rname);	fprintf(codfp, "\t\t.type %s, @function\n", ptab->rname);	fprintf(codfp, "%s:\n", ptab->rname);	fprintf(codfp, "\t\tpushl\t%%ebp\n");	fprintf(codfp, "\t\tmovl\t%%esp, %%ebp\n");    if(ptab->defn == DEF_FUNCT)        fprintf(codfp,"\t\tsubl\t$8, %%esp\n");    fprintf(codfp,"\t\tsubl\t$%d, %%esp\n",ptab->local_size);}static void emit_linux_local_args(symtab *ptab){    symbol *p;    char tp[10];    for(p = ptab->locals; p->next; p = p->next)    {        switch(p->type->type_id)        {        case TYPE_CHAR:            sprintf(tp, "byte  ptr");            break;        case TYPE_INTEGER:        case TYPE_BOOLEAN:            sprintf(tp, "word  ptr");            break;        case TYPE_REAL:            sprintf(tp, "dword  ptr");            break;        case TYPE_ARRAY:            if(p->type_link->last->type->type_id ==                    TYPE_INTEGER                    || p->type_link->last->type->type_id ==                    TYPE_BOOLEAN)

⌨️ 快捷键说明

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