📄 x86dos.c
字号:
case TYPE_BOOLEAN: if (p->tab->level) { fprintf(codfp, "\t\tpop\tbx\n"); fprintf(codfp, "\t\tpop\tax\n"); fprintf(codfp, "\t\tmov\tword ptr [bx],ax\n"); } else fprintf(codfp, "\t\tmov\tword ptr %s, ax\n",p->rname); break; case TYPE_STRING: fprintf(codfp, "\t\tmov\tcx, %04xh\n", strlen(p->v.s)); fprintf(codfp, "\t\tpop\tsi\n"); fprintf(codfp, "\t\tpop\tdi\n"); fprintf(codfp, "\t\tmov\tax,ds\n"); fprintf(codfp, "\t\tmov\tes,ax\n"); fprintf(codfp, "\t\tcld\n"); fprintf(codfp, "\t\trep\tmovsb\n"); break; case TYPE_REAL: fprintf(codfp, "\t\tmov\tax,%s\n",p->rname); fprintf(codfp, "\t\tmov\tdx,%s+2n",p->rname); break; case TYPE_ARRAY: if (p->type_link->last->type->type_id == TYPE_INTEGER ||p->type_link->last->type->type_id == TYPE_BOOLEAN ) { fprintf(codfp, "\t\tpop\tax\n"); fprintf(codfp, "\t\tpop\tbx\n"); fprintf(codfp, "\t\tmov\tword ptr [bx],ax\n"); } else if (p->type_link->last->type->type_id == TYPE_CHAR) { fprintf(codfp, "\t\tpop\tax\n"); fprintf(codfp, "\t\tpop\tbx\n"); fprintf(codfp, "\t\tmov\tbyte ptr [bx],al\n"); } break; default: break; }}static void do_dos_cond_jump(int true_or_false, Symbol label){ fprintf(codfp, "\t\tcmp\tax,1\n"); if (true_or_false) fprintf(codfp, "\t\tjge\t%s\n", label->name); else fprintf(codfp, "\t\tjl\t%s\n", label->name);}static void do_dos_jump(Symbol label){ fprintf(codfp, "\t\tjmp %s\n", label->name);}static void do_dos_label(Symbol label){ fprintf(codfp, "%s:\n", label->name);}static void do_dos_incr(Symbol sym){ switch (sym->type->type_id) { case TYPE_BOOLEAN: case TYPE_INTEGER: fprintf(codfp, "\t\tinc word ptr %s\n", sym->rname); break; case TYPE_CHAR: fprintf(codfp, "\t\tinc byte ptr %s\n", sym->rname); break; default: parse_error("incr instruction only support char, boolean and int.", ""); break; }}static void do_dos_decr(Symbol sym){ switch (sym->type->type_id) { case TYPE_BOOLEAN: case TYPE_INTEGER: fprintf(codfp, "dec word ptr %s\n", sym->rname); break; case TYPE_CHAR: fprintf(codfp, "dec byte ptr %s\n", sym->rname); break; default: parse_error("incr instruction only support char, boolean and int.", ""); break; }}static int jump_index = 0;static void do_dos_expression(Type type, int op){ if (type == NULL) { return; } if (type->type_id == TYPE_INTEGER || type->type_id == TYPE_BOOLEAN) { fprintf(codfp, "\t\tpop\tdx\n"); fprintf(codfp, "\t\tcmp\tdx,ax\n"); } else if(type->type_id == TYPE_CHAR) { fprintf(codfp, "\t\tpop\tdx\n"); fprintf(codfp, "\t\tcmp\tdl,al\n"); } else if (type->type_id == TYPE_STRING) { fprintf(codfp,"\t\tpop\tdi\n"); fprintf(codfp, "\t\tpop\tsi\n"); fprintf(codfp, "\t\tmov\tax,ds\n"); fprintf(codfp, "\t\tmov\tes,ax\n"); fprintf(codfp, "\t\tcld\n"); fprintf(codfp, "\t\tmov\tcx,0%xh\n",strlen(p->v.s)); fprintf(codfp, "\t\trepe\t\tcmpsb\n"); } else { parse_error("standard type expected.", ""); return; } fprintf(codfp, "\t\tmov\tax,1\n"); switch(generic(op)) { case GE: fprintf(codfp, "\t\tjge\tj_%03d\n", new_index(jump)); break; case LE: fprintf(codfp, "\t\tjle\tj_%03d\n", new_index(jump)); break; case GT: fprintf(codfp, "\t\tjg\tj_%03d\n", new_index(jump)); break; case LT: fprintf(codfp, "\t\tjl\tj_%03d\n", new_index(jump)); break; case EQ: fprintf(codfp, "\t\tje\tj_%03d\n", new_index(jump)); break; case NE: fprintf(codfp, "\t\tjne\tj_%03d\n", new_index(jump)); break; } fprintf(codfp, "\t\tsub\tax,ax\n"); fprintf(codfp, "j_%03d:\n", jump_index);}static void do_dos_negate(symbol *p){ if (!p) return; if (p->defn != DEF_VAR && p->defn != DEF_VALPARA && p->defn != DEF_VARPARA && p->defn != DEF_CONST) { parse_error("variable required.", ""); return; } switch(p->type->type_id) { case TYPE_INTEGER: fprintf(codfp, "\t\tneg\tax\n"); break; default: parse_error("operand type do not match operator.", ""); break; }}static void do_dos_expr(Type type, int op){ if (type == NULL) { return; } switch(generic(op)) { case ADD: if (type->type_id == TYPE_REAL) {} else if (type->type_id == TYPE_INTEGER) { fprintf(codfp,"\t\tpop\tdx\n"); fprintf(codfp, "\t\tadd\tax,dx\n"); } else parse_error("integer or real type expected.",""); break; case SUB: if (type->type_id == TYPE_REAL) {} else if (type->type_id==TYPE_INTEGER) { fprintf(codfp, "\t\tpop\tdx\n"); fprintf(codfp, "\t\tsub\tdx,ax\n"); fprintf(codfp, "\t\tmov\tax,dx\n"); } else parse_error("integer or real type expected.", ""); break; case OR: if (type->type_id == TYPE_BOOLEAN) { fprintf(codfp, "\t\tpop\tdx\n"); fprintf(codfp, "\t\tor\tax,dx\n"); } else parse_error("boolean type expected.", ""); break; default: break; }}static void do_dos_term(Type type, int op){ if (type == NULL) { return; } switch(generic(op)) { case MUL: if (type->type_id == TYPE_INTEGER) { fprintf(codfp, "\t\tpop\tdx\n"); fprintf(codfp, "\t\timul\tdx\n"); } else if (type->type_id == TYPE_REAL) {} else parse_error("integer or real type expected.", ""); break; case DIV: if (type->type_id == TYPE_INTEGER) { fprintf(codfp,"\t\tmov\tcx,ax\n"); fprintf(codfp, "\t\tpop\tax\n"); fprintf(codfp, "\t\tsub\tdx,dx\n"); fprintf(codfp, "\t\tidiv\tcx\n"); } else parse_error("integer type expected.", ""); break; case MOD: if (type->type_id == TYPE_INTEGER) { fprintf(codfp, "\t\tmov\tcx,ax\n"); fprintf(codfp, "\t\tpop\tax\n"); fprintf(codfp, "\t\tsub\tdx,dx\n"); fprintf(codfp, "\t\tidiv\tcx\n"); fprintf(codfp, "\t\tmov\tax,dx\n"); } else parse_error("integer type expected.",""); break; case AND: if (type->type_id != TYPE_BOOLEAN) parse_error("boolean type expected.",""); else { fprintf(codfp, "\t\tpop\tdx\n"); fprintf(codfp, "\t\tand\tax,dx\n"); } break; default: break; }}static void do_dos_factor(symbol *p){ symtab *ptab; int i; int n; if (!p) return; if (p->type->type_id == TYPE_ARRAY) { parse_error("array element expected",""); return; } if (p->defn == DEF_CONST || p->defn == DEF_ELEMENT) { switch(p->type->type_id) { case TYPE_BOOLEAN: fprintf(codfp, "\t\tmov\tax,%d\n",p->v.b); break; case TYPE_INTEGER: if (p->defn == DEF_ELEMENT) fprintf(codfp, "\t\tmov\tax,%s\n", p->rname); else { short tvi = (short)p->v.i; fprintf(codfp, "\t\tmov\tax,0%xh\n", tvi); } break; case TYPE_CHAR: fprintf(codfp, "\t\tmov\tal,'%c'\n",p->v.c); break; case TYPE_REAL: fprintf(codfp, "\t\tmov\tax,word ptr %s\n",p->rname); fprintf(codfp, "\t\tmov\tdx,word ptr %s+2\n",p->rname); break; case TYPE_STRING: fprintf(codfp, "\t\tlea\tax,%s\n",p->rname); break; default: break; } } else if (p->defn == DEF_VARPARA) { fprintf(codfp, "\t\tmov\tbx,word ptr %s\n", p->rname); fprintf(codfp, "\t\tmov\tax,word ptr [bx]\n"); } else if (p->defn == DEF_VAR ||p->defn == DEF_VALPARA) { if (p->tab == top_symtab_stack() || p->tab->level == 0) { switch(p->type->type_id) { case TYPE_CHAR: fprintf(codfp, "\t\tsub\tax,ax\n"); fprintf(codfp, "\t\tmov\tal,byte ptr %s\n",p->rname); break; case TYPE_BOOLEAN: case TYPE_INTEGER: fprintf(codfp, "\t\tmov\tax,word ptr %s\n",p->rname); break; case TYPE_REAL: fprintf(codfp, "\t\tmov\tax,word ptr %s\n",p->rname); fprintf(codfp, "\t\tmov\tdx,word ptr %s+2n",p->rname); break; } } if (p->defn == DEF_VAR) { ptab = top_symtab_stack(); n = ptab->level - p->tab->level; if (n <= 0) return; fprintf(codfp, "\t\tmov\tbx,bp\n"); for(i = 0; i<n; i++) fprintf(codfp, "\t\tmov\tbp,%s\n", LABEL_SLINK); switch(p->type->type_id) { case TYPE_INTEGER: case TYPE_BOOLEAN: fprintf(codfp, "\t\tmov\tax,word ptr %s\n",p->rname); break; case TYPE_CHAR: fprintf(codfp, "\t\tmov\tal,byte ptr %s\n",p->rname); break; default: break; } fprintf(codfp,"\t\tmov\tbp,bx\n"); } }}static void do_dos_not_factor(symbol *p){ if (!p) return; if (p->type->type_id!= TYPE_BOOLEAN) parse_error("Boolean type expected. ",""); do_dos_factor(p); fprintf(codfp, "\t\tand\tax, 1\n"); fprintf(codfp, "\t\txor\tax, 1\n");}static void do_dos_array_factor(symbol *p){ if (p->type_link->first->v.i >= 0) fprintf(codfp, "\t\tsub\tax,0%xh\n", p->type_link->first->v.i); else fprintf(codfp, "\t\tsub\tax,-0%xh\n", -(p->type_link->first->v.i)); fprintf(codfp, "\t\tmov\tcx,0%xh\n", get_symbol_size(p->type_link->last)); fprintf(codfp, "\t\timul\tcx\n"); fprintf(codfp, "\t\tpop\tdx\n"); if (p->tab->level) fprintf(codfp, "\t\tsub\tdx,ax\n"); else fprintf(codfp, "\t\tadd\tdx,ax\n"); fprintf(codfp, "\t\tpush\tdx\n");}static void do_dos_record_factor(symbol *var, symbol *p){ if (!var || !p || p->defn != DEF_FIELD) return; fprintf(codfp, "\t\tpop\tax\n"); fprintf(codfp, "\t\tmov\tdx,0%xh\n",p->offset); if (var->tab->level) fprintf(codfp, "\t\tsub\tax,dx\n"); else fprintf(codfp, "\t\tadd\tax,dx\n"); fprintf(codfp, "\t\tpush\tax\n");}static int programbegin(Env *global){ emit_dos_program_prologue(global->u.program.tab); return 0;}static int programend(Env *global){ emit_dos_program_epilogue(global->u.program.tab); return 0;}static int mainbegin(Env *main){ emit_dos_main_prologue(main->u.main.tab); return 0;}static int mainend(Env *main){ emit_dos_main_epilogue(main->u.main.tab); return 0;}static int globalvariable(Symbol symbol){ return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -