📄 x86.c
字号:
switch(p->type->type_id) { case TYPE_CHAR: fprintf(codfp,"\t\tsub\tax.ax\n"); fprintf(codfp,"\b\t\tmov\tal, byte ptr %s\n" ,p->rname); break; case TYPE_REAL: fprintf(codfp,"\t\t\tmov\tax, word ptr %s\n",p->rname); fprintf(datfp,"\t\t\tmov\tdx, word ptr %s+2\n",p->rname); break; case TYPE_INTEGER: case TYPE_BOOLEAN: fprintf(codfp,"\t\t\tmov\tax, word ptr %s\n",p->rname); break; case TYPE_ARRAY: fprintf(codfp,"\t\tpop\tbx\n"); if(p->type_link->last->type->type_id == TYPE_INTEGER ||p->type_link->last->type->type_id == TYPE_BOOLEAN) fprintf(codfp, "\t\tmov\tax,word ptr [bx]\n"); else if (p->type_link->last->type->type_id == TYPE_CHAR) fprintf(codfp, "\t\tmov\tal,byte ptr [bx]\n"); break; default: break; } }}STATIC void emit_load_address(symbol *p){ symtab *ptab; int n,i; switch(p->defn) { case DEF_VARPARA: fprintf(codfp, "\t\tmov\tax,word ptr %s\n", p->rname); break; case DEF_VAR: if(p->tab->level==0 || p->tab==top_symtab_stack()) { fprintf(codfp, "\t\tlea\tax,word ptr %s\n", p->rname); } else { ptab = top_symtab_stack(); n = p->tab->level - ptab->level + 1; fprintf(codfp,"\t\tmov\tbx,bp\n"); for (i = 0; i < n; i++) fprintf(codfp, "\t\tmov\tbp,%s\n", LABEL_SLINK); fprintf(codfp, "\t\tlea\tax,word ptr %s\n", p->rname); fprintf(codfp,"\t\tmov\tbp,bx\n"); } break; case DEF_VALPARA: fprintf(codfp, "\t\tmov\tax,word ptr %s\n", p->rname); break; default: break; }}STATIC void emit_load_element(){ fprintf(codfp, "\t\tmov\tcx,ax\n"); fprintf(codfp, "\t\tpop\tax\n"); fprintf(codfp, "\t\tadd\tax,cx\n");}STATIC void emit_load_field(symbol*p){ if(!p) return; fprintf(codfp, "\t\tpop\tbx\n"); switch(p->type->type_id) { case TYPE_INTEGER: case TYPE_BOOLEAN: fprintf(codfp,"\t\tmov\tax,word ptr [bx]\n"); break; case TYPE_CHAR: fprintf(codfp,"\t\tmov\tal,byte ptr [bx]\n"); break; default: break; }}STATIC int pop_stmt_stack(){ if(stmt_tos==STMT_STACK_SIZE) internal_error("Satement stack underflow.\n"); return stmt_stack[++stmt_tos];}STATIC void push_stmt_stack(int index){ if(stmt_tos==0) internal_error("Satement stack overflow.\n"); stmt_stack[stmt_tos--] = index;}STATIC int top_stmt_stack(){ return stmt_stack[stmt_tos + 1];}STATIC void do_function_assign(symtab *ptab, int srctype){ if(!ptab) return; if(ptab->type->type_id != srctype) { parse_error("operand type to not match operator.", ""); return; } switch(ptab->type->type_id) { case TYPE_CHAR: fprintf(codfp,"\t\txor\tah,ah\n"); fprintf(codfp,"\t\tmov\tbyte ptr %s,al\n", LABEL_RETVAL); break; case TYPE_BOOLEAN: case TYPE_INTEGER: fprintf(codfp,"\t\tmov\tword ptr %s,ax\n", LABEL_RETVAL); break; case TYPE_REAL: fprintf(codfp,"\t\tmov\tword ptr %s,ax\n", LABEL_RETVAL); fprintf(codfp,"\t\tmov\tword ptr %s,ax\n", LABEL_HIRETVAL); break; default: break; }}STATIC symbol *do_function_call(symtab *ptab){ int i,n; symbol *p; symtab *caller; symtab *callee; caller = top_symtab_stack(); callee = ptab; if(callee->defn != DEF_FUNCT) { parse_error("Undeclared function", callee->name); return NULL; } else if (callee->level == caller->level + 1) { fprintf(codfp,"\t\tpush\tbp\n"); } else if (callee->level == caller->level) { fprintf(codfp,"\t\tpush\t%s\n",LABEL_SLINK); } else if (callee->level < caller->level) { fprintf(codfp,"\t\tmov\tbx,bp\n"); n = caller->level - callee->level + 1; for(i =0; i<n; i++) fprintf(codfp, "\t\tmov\tbp,%s\n", LABEL_SLINK); fprintf(codfp,"\t\tpush\tbp\n"); fprintf(codfp,"\t\tmov\tbp,bx\n"); } else return NULL; fprintf(codfp,"\t\tcall rtn%03d\n", callee->id); for(p = ptab->locals; p->next; p = p->next) ; return p;}STATIC void do_procedure_call(symtab *ptab){ symtab *caller = top_symtab_stack(); symtab *callee = ptab; int n ; int i ; if(!caller || !callee) { parse_error("Undeclared procedure",""); return; } n = (callee->level) -(caller->level) + 1; if(callee->level==caller->level+1) { fprintf(codfp,"\t\tpush\tbp\n"); } else if (callee->level == caller->level) { fprintf(codfp, "\t\tpush\t%s\n", LABEL_SLINK); } else if(callee->level < caller->level) { fprintf(codfp,"\t\tmov\tbx,bp\n"); for(i = 0; i < n; i++) fprintf(codfp,"\t\tmov\tbp,%s\n", LABEL_SLINK); fprintf(codfp,"\t\tpush\tbp\n"); fprintf(codfp,"\t\tmov\tbp,bx\n"); } else return; fprintf(codfp,"\t\tcall\t%s\n", ptab->rname);}STATIC void reset_args(symtab *ptab){ rtn = ptab;}STATIC void do_first_arg(int ptype){ rtn = top_call_stack(); if(rtn) arg = rtn->args; else return; if(!arg) return; switch(arg->type->type_id) { case TYPE_REAL: if (ptype!=TYPE_REAL) fprintf(codfp,"\t\txor\tdx,dx\n"); fprintf(codfp,"\t\tpush\tdx\n"); fprintf(codfp,"\t\tpush\tax\n"); break; case TYPE_CHAR: fprintf(codfp,"\t\txor\tah,ah\n"); case TYPE_INTEGER: case TYPE_BOOLEAN: default: fprintf(codfp,"\t\tpush\tax\n"); break; }}STATIC void do_args(int ptype){ arg = top_call_symbol(); if(arg->next) arg = arg->next; else return; set_call_stack_top(arg); switch(arg->type->type_id) { case TYPE_REAL: if (ptype!=TYPE_REAL) fprintf(codfp,"\t\txor\tdx,dx\n"); fprintf(codfp,"\t\tpush\tdx\n"); fprintf(codfp,"\t\tpush\tax\n"); break; case TYPE_CHAR: fprintf(codfp,"\t\txor\tah.ah\n"); case TYPE_INTEGER: case TYPE_BOOLEAN: default: fprintf(codfp,"\t\tpush\tax\n"); break; }}STATIC void do_assign(symbol *p, int srctype){ symtab *ptab; int n,i; if (!p) return; if ((p->type->type_id != TYPE_ARRAY) && (p->type->type_id != TYPE_RECORD) && (p->type->type_id != srctype)) { parse_error("operand type do not match operator.",""); return; } switch(p->defn) { case DEF_VARPARA: fprintf(codfp,"\t\tpush\tax\nn"); fprintf(codfp,"\t\tmov\tax,word ptr %s\n", p->rname); break; case DEF_FIELD: fprintf(codfp,"\t\tpop\tbx\n"); if(p->type->type_id==TYPE_INTEGER ||p->type->type_id==TYPE_BOOLEAN) fprintf(codfp,"\t\tmov\tword ptr [bx],ax\n"); else if (p->type->type_id==TYPE_BOOLEAN) fprintf(codfp,"\t\tmov\tbyte ptr [bx],ax\n"); return; case DEF_VAR: case DEF_CONST: case DEF_ELEMENT: if(p->type->type_id==TYPE_ARRAY) { fprintf(codfp,"\t\tpush\tax\n"); break; } if(p->tab->level == 0 ||p->type->type_id==TYPE_REAL) break; else if( p->tab->level && p->tab == top_symtab_stack()) { fprintf(codfp,"\t\tpush\tax\n"); fprintf(codfp,"\t\tlea\tax,word ptr %s\n", p->rname); fprintf(codfp,"\t\tpush\tax\n"); break; } else { ptab = top_symtab_stack(); n = ptab->level - p->tab->level; fprintf(codfp,"\t\tpush\tax\n"); fprintf(codfp,"\t\tmov\tbx,bp\n"); for(i =0;i<n;i++) fprintf(codfp,"\t\tmov\tbp,%s\n", LABEL_SLINK); fprintf(codfp,"\t\tlea\tax,word ptr %s\n", p->rname); fprintf(codfp,"\t\tmov\tbp,bx\n"); fprintf(codfp,"\t\tpush\tax\n"); } break; case DEF_VALPARA: if(p->tab->level==0 || p->tab==top_symtab_stack()) fprintf(codfp,"\t\tpush\tax\n"); fprintf(codfp,"\t\tlea\tax,word ptr %s\n", p->rname); fprintf(codfp,"\t\tpush\tax\n"); break; default: parse_error("lvalue expected.",""); break; } switch(p->type->type_id) { case TYPE_CHAR: if(p->tab->level) { fprintf(codfp,"\t\tpop\tbx\n"); fprintf(codfp,"\t\tpop\tax\n"); fprintf(codfp,"\tmov\tbyte ptr [bx],al\n"); } else fprintf(codfp,"\t\tmov\tbyte ptr %s,al\n", p->rname); break; case TYPE_INTEGER: 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\tex, %04xh\n", strlen(p->v.s)); fprintf(codfp, "\t\tpop\tpop\tsi\n"); fprintf(codfp, "\t\tpop\tdi\n"); fprintf(codfp, "\t\tmov\tax,ds"); fprintf(codfp, "\t\tmov\tes,ax"); 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_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_jump(Symbol label){ fprintf(codfp, "\t\tjmp %s\n", label->name);}STATIC void do_label(Symbol label){ fprintf(codfp, "%s:\n", label->name);}STATIC void do_incr(Symbol sym){ switch (sym->type->type_id) { case TYPE_BOOLEAN: case TYPE_INTEGER: fprintf(codfp, "inc word ptr %s\n", sym->rname); break; case TYPE_CHAR: fprintf(codfp, "inc byte ptr %s\n", sym->rname); break; default: parse_error("incr instruction only support char, boolean and int.", ""); break; }}STATIC void do_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 void do_if_test(){ push_stmt_stack(new_index(stmt)); fprintf(codfp, "\t\tcmp\tax,1\n"); fprintf(codfp, "\t\tje\tif_t%04xh\n",top_stmt_stack( )); fprintf(codfp, "\t\tjmp\tif_f%04xh\n", top_stmt_stack()); fprintf(codfp, "if_t%04xh:\n",top_stmt_stack());}STATIC void do_if_clause( ){ fprintf(codfp, "\t\tjmp\tif_x%04xh\n", top_stmt_stack( )); fprintf(codfp, "if_f%04xh:\n",top_stmt_stack( ));}STATIC void do_if_exit(){ fprintf(codfp, "if_x%04xh:\n", pop_stmt_stack());}STATIC void do_repeat_start( ){ push_stmt_stack(new_index(stmt)); fprintf(codfp, "rep_%04xh:\n",top_stmt_stack( ));}STATIC void do_repeat_exit( ){ fprintf(codfp, "\t\tcmp\tax,1\n"); fprintf(codfp, "\t\tje\trep_x%04xh\n", top_stmt_stack()); fprintf(codfp, "\t\tjmp\trep_%04xh\n", top_stmt_stack()); fprintf(codfp, "\t\trep_x%04xh:\n", pop_stmt_stack( ));}STATIC void do_while_start( ){ push_stmt_stack (new_index(stmt)); fprintf(codfp, "wl_tst%04xh:\n",top_stmt_stack());}STATIC void do_while_expr( ){ fprintf(codfp, "\t\tcmp\tax,1\n"); fprintf(codfp, "\t\tje\twl%04xh\n", top_stmt_stack()); fprintf(codfp, "\t\tjmp\twl_x%04xh\n", top_stmt_stack()); fprintf(codfp, "wl%04xh:\n",top_stmt_stack());}STATIC void do_while_exit( ){ fprintf(codfp, "\t\tjmp\twl_tst%04xh\n", top_stmt_stack()); fprintf(codfp, "wl_x%04xh:\n", pop_stmt_stack());}void push_call_stack(symtab *p){ call_stk[call_tos] = p; call_sym[call_tos] = p->args; rtn = p; call_tos--; if (call_tos == -1) internal_error("call stack overflow.");}symtab *pop_call_stack(){ call_tos++; if (call_tos == MAX_CALL_LEVEL) internal_error("call stack underflow."); rtn = call_stk[call_tos]; arg = call_sym[call_tos]; return call_stk[call_tos];}symtab *top_call_stack( ){ return call_stk[call_tos + 1];}void set_call_stack_top(symbol *p){ call_sym[call_tos + 1] = p;}symbol *top_call_symbol( ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -