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

📄 x86dos.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_dos_write1(int arg_type);static void emit_dos_sqrt(int arg_type);static void emit_dos_odd(int arg_type);static void emit_dos_abs(int arg_type);static void emit_dos_sqr(int arg_type);static void emit_dos_read1(int arg_type);static void emit_dos_writeln(int arg_type);static int gen_level = 0;static void emit_dos_program_head();static void emit_dos_program_prologue(symtab *);static void emit_dos_program_epilogue(symtab *);static void emit_dos_main_prologue(symtab *);static void emit_dos_main_epilogue(symtab *);static void emit_dos_routine_prologue(symtab *);static void emit_dos_routine_epilogue(symtab *);static void emit_dos_local_args(symtab *);static void emit_dos_dos_push_op(Type ptype);static void emit_dos_load_value(symbol *);static void do_dos_function_assign(symtab *,int);static void do_dos_procedure_call(symtab *);static void do_dos_assign(symbol *, int);static void do_dos_expression(Type, int);static void do_dos_negate(symbol *);static void do_dos_expr(Type, int);static void do_dos_term(Type, int);static void do_dos_factor(symbol *);static void do_dos_array_factor(symbol *);static void do_dos_record_factor(symbol *, symbol *);static void do_dos_first_arg(int);static int emit_dos_address = 0;#define MICROSOFT_MASMstatic void do_dos_sys_routine(int routine_id, int arg_type){    switch(routine_id)    {    case fABS:        emit_dos_abs(arg_type);        break;    case fODD:        emit_dos_odd(arg_type);        break;    case  fPRED:        fprintf(codfp, "\t\tdec\tax\n");        break;    case  fSQR:        emit_dos_sqr(arg_type);        break;    case fSQRT:        emit_dos_sqrt(arg_type);        break;    case fSUCC:        fprintf(codfp, "\t\tinc\tax\n");        break;    case pREAD:        emit_dos_read1(arg_type);        break;    case pREADLN:        emit_dos_read1(arg_type);        break;    case pWRITE:        emit_dos_write1(arg_type);        break;    case  pWRITELN:        emit_dos_writeln(arg_type);        break;    default:        break;    }}static void emit_dos_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_dos_write1(int arg_type){    switch(arg_type)    {    case TYPE_BOOLEAN:    case TYPE_INTEGER:        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_dos_writeln(int arg_type){    switch(arg_type)    {    case TYPE_BOOLEAN:    case TYPE_INTEGER:        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_dos_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_dos_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_dos_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_dos_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_dos_program_prologue(symtab *ptab){#ifndef MICROSOFT_MASM    fprintf(codfp, " \n;alloc stack space\n");    fprintf(codfp, " \t\tdb\t%xh dup(?)\n"            ,STACK_SEG_SIZE);    fprintf(codfp,"\n_DATA\t\tends");#endif    fprintf(codfp,"\n\n;---program %s ---",ptab->name);#ifndef MICROSOFT_MASM    fprintf(codfp,"\n\n_TEXT\t\tsegment\tpublic\n\n");#else    fprintf(codfp,"\n\n.CODE\n");#endif    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_dos_program_head();#ifndef MICROSOFT_MASM    fprintf(datfp, " \n_DATA\t\tsegment\tpublic\n");#else    fprintf(datfp, " \n.DATA\n");#endif}/* char datname[]; */static void emit_dos_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");#ifdef MICROSOFT_MASM    fprintf(datfp,";small model\n");    fprintf(datfp,".MODEL SMALL\n");    fprintf(datfp,"\n;set stack size\n");    fprintf(datfp,".STACK %xh\n", STACK_SEG_SIZE);#endif}static void emit_dos_program_epilogue(symtab *ptab){    symbol *p;#ifndef MICROSOFT_MASM    fprintf(codfp,"\n_TEXT\t\tends\n");    fprintf(codfp,"\t\tend\tstart\n\n");#else    fprintf(codfp,"\n\n\t\t.STARTUP\n");    fprintf(codfp,"\t\tcall _main\n");    fprintf(codfp,"\n\n\t\t.EXIT\n");    fprintf(codfp,"\t\tend\n\n");#endif    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_dos_main_prologue(symtab *ptab){    fprintf(codfp,"\n\n; --- main routine ----\n");#ifndef MICROSOFT_MASM    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");#else    fprintf(codfp,"_main\t\tproc\tnear\n");    fprintf(codfp,"\t\tassume\tcs:_TEXT,ds:_DATA\n");    fprintf(codfp,"\t\tmov\tax,_DATA\n");    fprintf(codfp,"\t\tmov\tds,ax\n");#endif}static void emit_dos_main_epilogue(symtab *ptab){    fprintf(codfp,"\t\tret\n");    fprintf(codfp,"_main\t\tendp\n");}static void emit_dos_routine_prologue(symtab *ptab){    if(ptab->defn == DEF_PROG)        return;    fprintf(codfp,"\n\n; routine : %s \n",ptab->name);    emit_dos_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_dos_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");

⌨️ 快捷键说明

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