📄 x86.c
字号:
return call_sym[call_tos + 1];}STATIC void do_for_start(symbol *p){ sym_stk[sym_tos] = p; sym_tos--; switch(p->type->type_id) { case TYPE_CHAR: fprintf(codfp, "\t\tmov\tbyte ptr %s,al\n", p->rname); break; case TYPE_INTEGER: case TYPE_BOOLEAN: default: fprintf(codfp, "\t\tmov\tword ptr %s,ax\n", p->rname); break; } push_stmt_stack(new_index(stmt)); fprintf(codfp, "for_tst%04xh:\n",top_stmt_stack());}STATIC void do_for_test(int dir){ symbol *p = sym_stk[sym_tos+1]; direc_stk[dir_tos] = dir; dir_tos--; switch(p->type->type_id) { case TYPE_CHAR: fprintf(codfp, "\t\tcmp\tbyte ptr %s,al\n", p->rname); break; case TYPE_INTEGER: case TYPE_BOOLEAN: default: fprintf(codfp, "\t\tcmp\tword ptr %s,ax\n", p->rname); break; } if (dir == kDOWNTO) fprintf(codfp, "\t\tjge\tfor%04xh\n", top_stmt_stack()); else fprintf(codfp, "\t\tjle\tfor%04xh\n", top_stmt_stack()); fprintf(codfp, "\t\tjmp\tfor_x%04xh\n", top_stmt_stack()); fprintf(codfp, "for%04xh:\n",top_stmt_stack());}STATIC void do_for_exit(){ symbol *p = sym_stk[sym_tos + 1]; switch(p->type->type_id) { case TYPE_CHAR: if (direc_stk[dir_tos + 1] == kTO) fprintf(codfp, "\t\tinc\tbyte ptr %s\n", p->rname); else fprintf (codfp,"\t\tdec\tbyte ptr %s\n", p->rname); break; case TYPE_INTEGER: case TYPE_BOOLEAN: default: if ((direc_stk[dir_tos + 1] == kTO)) fprintf(codfp, "\t\tinc\tword ptr %s\n", p->rname); else fprintf (codfp, "\t\tdec\tword ptr %s\n", p->rname); break; } fprintf (codfp, "\t\tjmp\tfor_tst%04xh\n", top_stmt_stack()); fprintf(codfp, "for_x%04xh:\n", pop_stmt_stack()); switch(p->type->type_id) { case TYPE_CHAR: if (direc_stk[dir_tos+1] == kTO) fprintf(codfp, "\t\tdec\tbyte ptr %s\n", p->rname); else fprintf(codfp, "\t\tinc\tbyte ptr %s\n", p->rname); break; case TYPE_INTEGER: case TYPE_BOOLEAN: default: if (direc_stk[dir_tos+1] == kTO) fprintf(codfp, "\t\tdec\tword ptr %s\n", p->rname); else fprintf(codfp, "\t\tinc\tword ptr %s\n", p->rname); break; } sym_tos++; dir_tos++;}#define MAX_CASE_LEVEL 8STATIC int case_list_stk[MAX_CASE_LEVEL];STATIC int case_list_tos = MAX_CASE_LEVEL-1;#define MAX_CASE_ENTRY 32STATIC symbol *case_con_queue[MAX_CASE_ENTRY];STATIC int last_con = 0;STATIC int case_act_index = 1;STATIC void push_case_stack(int new_list){ if (case_list_tos==-1) internal_error( "case stack overflow."); else case_list_stk[case_list_tos--] = new_list;}STATIC int pop_case_stack(){ if (case_list_tos==MAX_CASE_LEVEL-1) { internal_error("case stack underflow."); return -1; } return case_list_stk[++case_list_tos];}STATIC int top_case_stack(){ if (case_list_tos==MAX_CASE_LEVEL-1) return -1; return case_list_stk[case_list_tos+1];}STATIC void enter_case_queue(symbol *p){ int i; if (last_con == MAX_CASE_ENTRY) internal_error("case queue overflow."); else { if (last_con == 0) { for(i = 0; i<MAX_CASE_ENTRY; i++) case_con_queue[i] = NULL; } case_con_queue[last_con] = p; last_con++; }}STATIC void do_case_start( ){ push_stmt_stack(new_index(stmt)); fprintf(codfp, "\t\tpush\tcx\n"); fprintf(codfp, "\t\tmov\tcx,ax\n"); fprintf(codfp, "\t\tjmp\tcs%d_tst\n", top_stmt_stack()); push_case_stack(last_con);}STATIC void do_case_test(){ symbol *p; int i; fprintf (codfp, "cs%d_tst:\n",top_stmt_stack( )); i = top_case_stack(); for(;i<last_con;i++) { p = case_con_queue[i]; switch(p->type->type_id) { case TYPE_BOOLEAN: case TYPE_INTEGER: if (p->defn==DEF_ELEMENT) fprintf(codfp, "\t\tmov\tax,%s\n", p->rname); else if (p->v.i>=0) fprintf(codfp, "\t\tmov\tax,0%xh\n",p->v.i); else fprintf(codfp, "\t\tmov\tax,-0%xh\n",-p->v.i); 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; } if (p->type->type_id == TYPE_INTEGER || p->type->type_id == TYPE_BOOLEAN) fprintf(codfp, "\t\tcmp\tcx,ax\n"); else if (p->type->type_id == TYPE_CHAR) fprintf(codfp, "\t\tcmp\tcl,al\n"); fprintf(codfp, "\t\tjne\tcs%dn_0%xh\n", top_stmt_stack(),i-top_case_stack()+1); fprintf(codfp, "\t\tjmp\tcs%da_%04xh\n", top_stmt_stack(),i-top_case_stack()+1); fprintf(codfp, "cs%dn_0%xh:\n",top_stmt_stack() ,i-top_case_stack()+1); case_con_queue[i] = NULL; } fprintf(codfp, "cs%d_x:\n",pop_stmt_stack()); fprintf(codfp, "\t\tpop\tcx\n"); last_con = pop_case_stack( );}STATIC void add_case_const(symbol *p){ case_act_index = last_con - top_case_stack() + 1; enter_case_queue(p); fprintf(codfp, "cs%da_%04xh:\n",top_stmt_stack(), case_act_index);}STATIC void do_case_jump(){ fprintf(codfp,"\t\tjmp\tcs%d_x\n",top_stmt_stack());}STATIC int jump_index = 0;STATIC void do_expression(symbol *p, int op){ if (p->type->type_id == TYPE_INTEGER || p->type->type_id == TYPE_BOOLEAN) { fprintf(codfp, "\t\tpop\tdx\n"); fprintf(codfp, "\t\tcmp\tdx,ax\n"); } else if(p->type->type_id == TYPE_CHAR) { fprintf(codfp, "\t\tpop\tdx\n"); fprintf(codfp, "\t\tcmp\tdl,al\n"); } else if (p->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(op) { case oGE: fprintf(codfp, "\t\tjge\tj_%03d\n", new_index(jump)); break; case oLE: fprintf(codfp, "\t\tjle\tj_%03d\n", new_index(jump)); break; case oGT: fprintf(codfp, "\t\tjg\tj_%03d\n", new_index(jump)); break; case oLT: fprintf(codfp, "\t\tjl\tj_%03d\n", new_index(jump)); break; case oEQUAL: fprintf(codfp, "\t\tje\tj_%03d\n", new_index(jump)); break; case oUNEQU: 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_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_expr(symbol *p, int op){ if (!p) return; switch(op) { case oPLUS: if (p->type->type_id == TYPE_REAL) {} else if (p->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 oMINUS: if (p->type->type_id == TYPE_REAL) {} else if (p->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 kOR: if (p->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_term(symbol *p, int op){ if (!p) return; switch(op) { case oMUL: if (p->type->type_id == TYPE_INTEGER) { fprintf(codfp, "\t\tpop\tdx\n"); fprintf(codfp, "\t\timul\tdx\n"); } else if (p->type->type_id == TYPE_REAL) {} else parse_error("integer or real type expected.", ""); break; case kDIV: case oDIV: if (p->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 kMOD: if (p->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 kAND: if (p->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_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 fprintf(codfp, "\t\tmov\tax,0%0xh\n", p->v.i); 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_INTEGER: case TYPE_BOOLEAN: 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_not_factor(symbol *p){ if (!p) return; if (p->type->type_id!= TYPE_BOOLEAN) parse_error("Boolean type expected. ",""); do_factor(p); fprintf(codfp, "\t\tand\tax, 1\n"); fprintf(codfp, "\t\txor\tax, 1\n");}STATIC void do_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_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");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -