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

📄 x86.c

📁 浙江大学编译原理课程设计源代码,高等院校计算机专业
💻 C
📖 第 1 页 / 共 3 页
字号:
/** * for backend without generate ast forest. */#define  X86_DOS#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 16#ifdef GENERATE_AST#define STATIC static#else#define STATIC#endif/*static Symbol	p;static Symtab	ptab;*/static symtab *rtn =NULL;static symbol *arg = NULL;STATIC int sym_tos = MAX_LOOP_LEVEL-1;STATIC int direc_stk[MAX_LOOP_LEVEL];STATIC int dir_tos = MAX_LOOP_LEVEL-1;STATIC int stmt_tos = STMT_STACK_SIZE - 1;STATIC int stmt_stack[STMT_STACK_SIZE];STATIC symbol *sym_stk[MAX_LOOP_LEVEL];STATIC int stmt_index = 0;STATIC int call_tos = MAX_CALL_LEVEL-1;STATIC symbol *call_sym[MAX_CALL_LEVEL];STATIC symtab *call_stk[MAX_CALL_LEVEL];STATIC void emit_write1(int arg_type);STATIC void emit_sqrt(int arg_type);STATIC void emit_odd(int arg_type);STATIC void emit_abs(int arg_type);STATIC void emit_sqr(int arg_type);STATIC void emit_read1(int arg_type);STATIC void emit_writeln(int arg_type);STATIC symbol *do_function_call(symtab *);STATIC void emit_program_head();STATIC void emit_program_prologue(symtab *);STATIC void emit_program_epilogue(symtab *);STATIC void emit_main_prologue(symtab *);STATIC void emit_main_epilogue(symtab *);STATIC void emit_routine_prologue(symtab *);STATIC void emit_routine_epilogue(symtab *);STATIC void emit_local_args(symtab *);STATIC void emit_push_op(int);STATIC void emit_load_value(symbol *);STATIC void do_function_assign(symtab *,int);STATIC void do_procedure_call(symtab *);STATIC void do_assign(symbol *, int);STATIC void do_if_test();STATIC void do_if_caluse();STATIC void do_if_exit();STATIC void do_repeat_start();STATIC void do_repeat_exit();STATIC void do_while_start();STATIC void do_while_expr();STATIC void do_while_exit();STATIC void do_for_start(symbol *);STATIC void do_for_test(int);STATIC void do_for_exit();STATIC void do_expression(symbol *, int);STATIC void do_negate(symbol *);STATIC void do_expr(symbol *, int);STATIC void do_term(symbol *, int);STATIC void do_factor(symbol *);STATIC void do_no_factor(symbol *);STATIC void do_array_factor(symbol *);STATIC void do_record_factor(symbol *, symbol *);STATIC void do_first_arg(int);STATIC void reset_args(symtab *);STATIC void push_stmt_stack(int);STATIC int pop_stmt_stack();STATIC int top_stmt_stack();STATIC int rout_index = 0;STATIC void do_sys_routine(int routine_id, int arg_type){    switch(routine_id)    {    case fABS:        emit_abs(arg_type);        break;    case fODD:        emit_odd(arg_type);        break;    case  fPRED:        fprintf(codfp, "\t\tdec\tax\n");        break;    case  fSQR:        emit_sqr(arg_type);        break;    case fSQRT:        emit_sqrt(arg_type);        break;    case fSUCC:        fprintf(codfp, "\t\tinc\tax\n");        break;    case pREAD:        emit_read1(arg_type);        break;    case pREADLN:        emit_read1(arg_type);        break;    case pWRITE:        emit_write1(arg_type);        break;    case  pWRITELN:        emit_writeln(arg_type);        break;    default:        break;    }}STATIC void emit_read1(int arg_type){    fprintf(codfp, "\t\tpush\tax\n");    fprintf(codfp, "\t\tpush\tbp\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;    }}STATIC void emit_write1(int arg_type){    switch(arg_type)    {    case TYPE_INTEGER:	case TYPE_BOOLEAN:        fprintf(codfp, "\t\tpush\tax\n");        fprintf(codfp, "\t\tpush\tbp\n");        fprintf(codfp, "\t\tcall\t_write_int\n");        break;    case TYPE_CHAR:        fprintf(codfp, "\t\tmov\tdl,al\n");        fprintf(codfp, "\t\tmov\tah,2\n");        fprintf(codfp, "\t\tint\t21h\n");        break;    case TYPE_STRING:        fprintf(codfp, "\t\tpush\tax\n");        fprintf(codfp, "\t\tpush\tbp\n");        fprintf(codfp, "\t\tcall\t_write_string\n");        break;    default:        break;    }}STATIC void emit_writeln(int arg_type){    switch(arg_type)    {    case TYPE_INTEGER:	case TYPE_BOOLEAN:        fprintf(codfp, "\t\tpush\tax\n");        fprintf(codfp, "\t\tpush\tbp\n");        fprintf(codfp, "\t\tcall\t_writeln_int\n");        break;    case TYPE_CHAR:        fprintf(codfp, "\t\tmov\tdl,al\n");        fprintf(codfp, "\t\tmov\tah,2\n");        fprintf(codfp, "\t\tint\t21h\n");        fprintf(codfp, "\t\tmov\tdl,13\n");        fprintf(codfp, "\t\tint\t21h\n");        fprintf(codfp, "\t\tmov\tdl,10\n");        fprintf(codfp, "\t\tint\t21h\n");        break;    case  TYPE_STRING:        fprintf(codfp, "\t\tpush\tax\n");        fprintf(codfp, "\t\tpush\tbp\n");        fprintf(codfp, "\t\tcall\t_writeln_string\n");        break;    default:        break;    }}STATIC void emit_abs(int arg_type){    fprintf(codfp, "\t\tpush\tbp\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\txor\tah,ah\n");        fprintf(codfp, "\t\tcall\t_abs_int\n");        break;    default:        break;    }}STATIC void emit_sqr(int arg_type){    fprintf(codfp, "\t\tpush\tbp\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\txor\tah,ah\n");        fprintf(codfp, "\t\tcall\t_sqr_int\n");        break;    default:        break;    }}STATIC void emit_odd(int arg_type){    fprintf(codfp, "\t\tpush\tbp\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\txor\tah,ah\n");        fprintf(codfp, "\t\tcall\t_odd_int\n");        break;    default:        break;    }}STATIC void emit_sqrt(int arg_type){    fprintf(codfp, "\t\tpush\tbp\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\txor\tah,ah\n");        fprintf(codfp, "\t\tcall\t_sqrt_int\n");        break;    default:        break;    }}STATIC void emit_program_prologue(symtab *ptab){    fprintf(codfp, " \n;alloc stack space\n");    fprintf(codfp, " \t\tdb\t0%xh dup(?)\n"            ,STACK_SEG_SIZE);    fprintf(codfp,"\n_DATA\t\tends");    fprintf(codfp,"\n\n;---program %s ---",ptab->name);    fprintf(codfp,"\n\n_TEXT\t\tsegment\tpublic\n\n");    fprintf(codfp,"\t\tinclude\tx86rtl.inc\n\n");    fprintf(codfp,"%s\tequ\tword ptr [bp+04h]\n"            ,LABEL_SLINK);    fprintf(codfp,"%s\tequ\tword ptr [bp-04h]\n",            LABEL_RETVAL);    fprintf(codfp,"%s\tequ\tword ptr [bp-02h]\n",            LABEL_HIRETVAL);    emit_program_head();    fprintf(datfp, " \n_DATA\t\tsegment\tpublic\n");}/* char datname[]; */STATIC void emit_program_head(){#ifdef _MSDOS_    struct dosdate_t d;    struct dosdate_t t;    _dos_getdate(&d);    _dos_gettime(&t);    fprintf(datfp,";%s\n;%02d:%02d:%02d/%d/%d/%d\n",            t.hour,t.minute,t.second,d.month,d.day,d.year);#elif defined __linux__    time_t now;    struct tm *tv;    time(&now);    tv = gmtime(&now);    fprintf(datfp, ";%04d/%02d/%02d\n;%02d:%02d:%02d\n",            tv->tm_year + 100, tv->tm_mon, tv->tm_mday,            tv->tm_hour, tv->tm_min, tv->tm_sec);#endif    fprintf(datfp,";\n");    fprintf(datfp,";SPL Compiler Ver %s\n",_PC_VER_);	fprintf(datfp, "\n\n.MODEL SMALL\n");}STATIC void emit_program_epilogue(symtab *ptab){    symbol *p;    fprintf(codfp,"\n_TEXT\t\tends\n");    fprintf(codfp,"\t\tend\tstart\n\n");    fprintf(datfp,"\n;global variables\n");    for(p = ptab->locals; p; p = p->next)    {        switch (p->type->type_id)        {        case 	TYPE_CHAR:            fprintf(datfp,"%s\t\tdb\t",p->rname);            break;		case	TYPE_BOOLEAN:        case 	TYPE_INTEGER:            fprintf(datfp,"%s\t\tdw\t",p->rname);            break;        case 	TYPE_REAL:            fprintf(datfp,"%s\t\tdd\t",p->rname);            break;        case 	TYPE_STRING:            fprintf(datfp,"%s\t\tdb\t%s\n",p->rname,                    p->v.s);            fprintf(datfp,"\t\tdb\t'$'\n");            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);            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);            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);            continue;        default:            break;        }        if (p->defn == DEF_CONST)        {            switch(p->type->type_id)            {            case TYPE_CHAR:                fprintf(datfp,"'%c'\n",p->v.c);                break;            case TYPE_INTEGER:                if (p->v.i >= 0)                    fprintf(datfp, "0%xh\n", p->v.i);                break;            case TYPE_REAL:                fprintf(datfp, "%g\n", p->v.f);                break;            case TYPE_STRING:                break;            default:                fprintf(datfp,"?\n");            }        }        else            fprintf(datfp,"?\n");    }}STATIC void emit_main_prologue(symtab *ptab){    fprintf(codfp,"\n\n; --- main routine ----\n");    fprintf(codfp,"_main\t\tproc\tfar\n");    fprintf(codfp,"\t\tassume\tcs:_TEXT,ds:_DATA\n");    fprintf(codfp,"start:\n");    fprintf(codfp,"\t\tpush\tds\n");    fprintf(codfp,"\t\tsub\tax,ax\n");    fprintf(codfp,"\t\tpush\tax\n");    fprintf(codfp,"\t\tmov\tax,_DATA\n");    fprintf(codfp,"\t\tmov\tds,ax\n");}STATIC void emit_main_epilogue(symtab *ptab){    fprintf(codfp,"\t\tret\n");    fprintf(codfp,"_main\t\tendp\n");}STATIC void emit_routine_prologue(symtab *ptab){    if(ptab->defn == DEF_PROG)        return;    fprintf(codfp,"\n\n; routine : %s \n",ptab->name);    emit_local_args(ptab);    fprintf(codfp,";routine code\n");    fprintf(codfp,"%s\t\tproc\n", ptab->rname);    fprintf(codfp,"\t\tassume\tcs:_TEXT,ds:_DATA\n");    fprintf(codfp,"\t\tmov\tax,_DATA\n");    fprintf(codfp,"\t\tmov\tds,ax\n");    fprintf(codfp,"\t\tpush\tbp\n");    fprintf(codfp,"\t\tmov\tbp,sp\n");    if(ptab->defn == DEF_FUNCT)        fprintf(codfp,"\t\tsub\tsp, 4\n");    fprintf(codfp,"\t\tsub\tsp,%04xh\n",ptab->local_size);}STATIC void emit_local_args(symtab *ptab){    symbol *p;    char tp[10];    fprintf(codfp,";local variables in %s\n",ptab->name);    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)                sprintf(tp, "word	ptr");            else if (p->type_link->last->type->type_id == TYPE_CHAR)                sprintf(tp, "byte	ptr");            break;        case TYPE_RECORD:            sprintf(tp, "byte  ptr");            break;        default:            break;        }        fprintf(codfp,"	%s\t\tequ\t%s	[bp-%04xh]\n",                p->rname,tp,p->offset);    }    fprintf(codfp,"; arguments in %s\n", ptab->name);    for(p =ptab->args;p ;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;        default:            break;        }        fprintf(codfp,"%s\t\tequ\t%s	[bp+%04xh]\n",                p->rname,tp,p->offset);    }}STATIC void emit_routine_epilogue(symtab *ptab){    if(ptab->defn == DEF_PROG)        return;    if(ptab->defn == DEF_FUNCT)    {        switch(ptab->type->type_id)        {        case  TYPE_INTEGER:        case  TYPE_BOOLEAN:            fprintf(codfp,"\n\t\tmov\tax, word ptr %s\n",LABEL_RETVAL);            break;        case  TYPE_CHAR:            fprintf(codfp,"\n\t\tmov\tah, 0\n");            fprintf(codfp,"\n\t\tmov\tax, byte  ptr %s\n",                    LABEL_RETVAL);            break;        case  TYPE_REAL:            fprintf(codfp,"\n\t\tmov\tax,%s\n",                    LABEL_RETVAL);            fprintf(codfp,"\n\t\tmov\tdx,%s\n",                    LABEL_HIRETVAL);            break;        }    }    fprintf(codfp,"\t\tmov\tsp,bp\n");    fprintf(codfp,"\t\tpop\tbp\n");    fprintf(codfp,"\t\tret\t%04xh\n",ptab->args_size + 2);    fprintf(codfp,"\n%s\t\tendp\n",ptab->rname);}STATIC void emit_push_op(int ptype){    switch(ptype)    {    case  TYPE_CHAR:    case  TYPE_BOOLEAN:    case  TYPE_INTEGER:        fprintf(codfp,"\t\tpush\tax\n");        break;    case  TYPE_REAL:        fprintf(codfp,"\t\tpush\tdx\n");        fprintf(codfp,"\t\tpush\tax\n");        break;    }}STATIC void emit_load_value(symbol *p){    if(p->defn==DEF_VARPARA)    {        fprintf(codfp,"\t\tmov\tbx,word ptr [bp+4]\n");        switch(p->type->type_id)        {        case  TYPE_CHAR:            fprintf(codfp,"\t\txor\tah, ah\n");            fprintf(codfp,"\t\tmov\tal, byte ptr [bx]\n");            break;        case TYPE_REAL:            fprintf(codfp,"\t\tmov\tax,word ptr [bx]\n");            fprintf(codfp,"\t\tmov\tdx,word ptr [bx+2]\n");            break;        case  TYPE_INTEGER:        case  TYPE_BOOLEAN:            fprintf(codfp,"\t\tmov\tax,word ptr [bx]\n");            break;        }    }    else if (p->tab->level==0             ||p->tab==top_symtab_stack())    {

⌨️ 快捷键说明

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