📄 x86linux.c
字号:
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; } snprintf(p->rname, sizeof(p->rname) - 1, "-%d(%%ebp)", p->offset); } 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; } snprintf(p->rname,sizeof(p->rname) - 1,"%d(%%ebp)", p->offset); }}static void emit_linux_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\tmovl\t%s, %%eax\n", LABEL_RETVAL); */ fprintf(codfp,"\n\t\tmovl\t%s, %%eax\n", LABEL_RETVAL); break; case TYPE_CHAR: fprintf(codfp,"\n\t\txorb\t%%ah, %%ah\n"); fprintf(codfp,"\n\t\tmovl\t%s, %%eax\n", LABEL_RETVAL); /* fprintf(codfp,"\n\t\tmovl\t%s, %%eax\n", LABEL_RETVAL); */ break; case TYPE_REAL: break; } } /* fprintf(codfp,"\t\tmov\tsp,bp\n"); fprintf(codfp,"\t\tpop\tbp\n"); */ fprintf(codfp, "\t\tleave\n"); /* fprintf(codfp,"\t\tret\t%04xh\n",ptab->args_size + 2); fprintf(codfp,"\n%s\t\tendp\n",ptab->rname); */ fprintf(codfp, "\t\tret\n"); fprintf(codfp, "\t\t.size %s, .-%s\n", ptab->rname, ptab->rname);}static void emit_linux_dos_push_op(Type ptype){ switch(ptype->type_id) { case TYPE_CHAR: case TYPE_BOOLEAN: case TYPE_INTEGER: fprintf(codfp,"\t\tpushl\t%%eax\n"); break; case TYPE_REAL: fprintf(codfp,"\t\tpushl\t%%edx\n"); fprintf(codfp,"\t\tpushl\t%%eax\n"); break; }}static void emit_linux_load_value(symbol *p){ if(p->defn == DEF_VARPARA) { /* fprintf(codfp,"\t\tmov\tbx,word ptr [bp+4]\n"); */ fprintf(codfp,"\t\tmovl\t4(%%ebp), %%ebx\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"); */ fprintf(codfp,"\t\txorl\t%%eax, %%eax\n"); fprintf(codfp,"\t\tmovb\t(%%ebx), %%al\n"); break; case TYPE_REAL: /* fprintf(codfp,"\t\tmov\tax,word ptr [bx]\n"); fprintf(codfp,"\t\tmov\tdx,word ptr [bx+2]\n"); */ fprintf(codfp,"\t\tmovl\t(%%ebx), %%eax\n"); fprintf(codfp, "\t\tmovl\t4(%%ebx), %%edx\n"); break; case TYPE_INTEGER: case TYPE_BOOLEAN: /* fprintf(codfp,"\t\tmov\tax,word ptr [bx]\n"); */ fprintf(codfp,"\t\tmovl\t(%%ebx), %%eax\n"); break; } } else if (p->tab->level==0 ||p->tab==top_symtab_stack()) { 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); */ fprintf(codfp,"\t\tsubl\t%%eax, %%eax\n"); fprintf(codfp,"\b\t\tmovb\t%s, %%al\n" ,p->rname); break; case TYPE_REAL: break; case TYPE_INTEGER: case TYPE_BOOLEAN: /* fprintf(codfp,"\t\t\tmov\tax, word ptr %s\n",p->rname); */ fprintf(codfp,"\t\t\tmovl\t%s, %%eax\n",p->rname); break; case TYPE_ARRAY: fprintf(codfp,"\t\tpopl\t%%ebx\n"); if(p->type_link->last->type->type_id == TYPE_INTEGER ||p->type_link->last->type->type_id == TYPE_BOOLEAN) fprintf(codfp, "\t\tmovl\t(%%ebx), %%eax\n"); else if (p->type_link->last->type->type_id == TYPE_CHAR) fprintf(codfp, "\t\tmovb\t(%%ebx), %%al\n"); break; default: break; } }}static void emit_linux_load_address(symbol *p){ symtab *ptab; int n,i; switch(p->defn) { case DEF_VARPARA: fprintf(codfp, "\t\tmovl\t%s, %%eax\n", p->rname); break; case DEF_VAR: if(p->tab->level == 0 || p->tab == top_symtab_stack()) { /* fprintf(codfp, "\t\tmov\tax,word ptr %s\n", p->rname); */ fprintf(codfp, "\t\tleal\t%s, %%eax\n", p->rname); } else { ptab = top_symtab_stack(); n = p->tab->level - ptab->level + 1; fprintf(codfp,"\t\tmovl\t%%ebp, %%ebx\n"); for (i = 0; i < n; i++) fprintf(codfp, "\t\tmovl\t%s, %%ebp\n", LABEL_SLINK); fprintf(codfp, "\t\tleal\t%s, %%eax\n", p->rname); fprintf(codfp,"\t\tmovl\t%%ebx, %%ebp\n"); } break; case DEF_VALPARA: fprintf(codfp, "\t\tleal\t%s, %%eax\n", p->rname); break; default: break; }}static void emit_linux_load_field(symbol*p){ if(!p) return; fprintf(codfp, "\t\tpopl\t%%ebx\n"); switch(p->type->type_id) { case TYPE_INTEGER: case TYPE_BOOLEAN: fprintf(codfp,"\t\tmovl\t(%%ebx), %%eax\n"); break; case TYPE_CHAR: fprintf(codfp,"\t\tmovb\t(%%ebx), %%al\n"); break; default: break; }}static void do_linux_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\txorb\t%%ah, %%ah\n"); fprintf(codfp, "\t\tmovl\t%%eax, %s\n", LABEL_RETVAL); /* fprintf(codfp,"\t\txorb\t%%ah, %%ah\n"); fprintf(codfp,"\t\tmovl\t%%al, %s\n", LABEL_RETVAL); */ break; case TYPE_BOOLEAN: case TYPE_INTEGER: fprintf(codfp, "\t\tmovl\t%%eax, %s\n", LABEL_RETVAL); /* fprintf(codfp,"\t\tmovl\t%%eax, %s\n", LABEL_RETVAL); */ break; case TYPE_REAL: break; default: break; }}static void do_linux_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\tpushl\t%%ebp\n"); } else if (callee->level == caller->level) { fprintf(codfp, "\t\tpushl\t%s\n", LABEL_SLINK); } else if(callee->level < caller->level) { fprintf(codfp,"\t\tmovl\t%%ebp, %%ebx\n"); for(i = 0; i < n; i++) fprintf(codfp,"\t\tmovl\t%s, %%ebp\n", LABEL_SLINK); fprintf(codfp,"\t\tpushl\t%%ebp\n"); fprintf(codfp,"\t\tmovl\t%%ebx, %%ebp\n"); } else return; fprintf(codfp,"\t\tcall\t%s\n", ptab->rname); fprintf(codfp, "\t\taddl\t$%d, %%esp\n", ptab->args_size + IR->intmetric.size);}static void do_linux_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: break; case TYPE_CHAR: fprintf(codfp,"\t\txorb\t%%ah, %%ah\n"); case TYPE_INTEGER: case TYPE_BOOLEAN: default: fprintf(codfp,"\t\tpushl\t%%eax\n"); break; }}static void do_linux_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: break; case TYPE_CHAR: fprintf(codfp,"\t\txorb\t%%ah, %%ah\n"); case TYPE_INTEGER: case TYPE_BOOLEAN: default: fprintf(codfp,"\t\tpushl\t%%eax\n"); break; }}static void do_linux_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; } if((p->type->type_id == TYPE_ARRAY) && (srctype != p->type->first->type->type_id)) { parse_error("operand type do not match operator.",""); return; } if((p->type->type_id == TYPE_RECORD)) { parse_error("operand type do not match operator.",""); return; } switch(p->defn) { case DEF_VARPARA: fprintf(codfp,"\t\tpushl\t%%eax\n"); fprintf(codfp,"\t\tmovl\t%s, %%eax\n", p->rname); break; case DEF_FIELD: fprintf(codfp,"\t\tpopl\t%%ebx\n"); if(p->type->type_id == TYPE_INTEGER ||p->type->type_id == TYPE_BOOLEAN) fprintf(codfp,"\t\tmovl\t%%eax, (%%ebx)\n"); else if (p->type->type_id == TYPE_CHAR) fprintf(codfp,"\t\tmovb\t%%al, (%%ebx)\n"); return; case DEF_VAR: case DEF_CONST: case DEF_ELEMENT: if(p->type->type_id == TYPE_ARRAY) { fprintf(codfp,"\t\tpushl\t%%eax\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\tpushl\t%%eax\n"); fprintf(codfp,"\t\tleal\t%s, %%eax\n", p->rname); fprintf(codfp,"\t\tpushl\t%%eax\n"); break; } else { ptab = top_symtab_stack(); n = ptab->level - p->tab->level; fprintf(codfp,"\t\tpushl\t%%eax\n"); fprintf(codfp,"\t\tmovl\t%%ebp, %%ebx\n"); for(i =0;i<n;i++) fprintf(codfp,"\t\tmovl\t%s,%%ebp\n", LABEL_SLINK); fprintf(codfp,"\t\tleal\t%s, %%eax\n", p->rname); fprintf(codfp,"\t\tmovl\t%%ebx, %%ebp\n"); fprintf(codfp,"\t\tpushl\t%%eax\n"); } break; case DEF_VALPARA: if(p->tab->level==0 || p->tab==top_symtab_stack()) fprintf(codfp,"\t\tpushl\t%%eax\n"); fprintf(codfp,"\t\tleal\t%s, %%eax\n", p->rname); fprintf(codfp,"\t\rpushl\t%%eax\n"); break; default: parse_error("lvalue expected.",""); break; } switch(p->type->type_id) { case TYPE_CHAR: if(p->tab->level) { fprintf(codfp,"\t\tpopl\t%%bx\n"); fprintf(codfp,"\t\tpopl\t%%ax\n"); fprintf(codfp,"\tmovb\t%%al, (%%bx)\n"); } else fprintf(codfp,"\t\tmovb\t%%al,%s\n", p->rname); break; case TYPE_INTEGER: case TYPE_BOOLEAN: if (p->tab->level) { fprintf(codfp, "\t\tpopl\t%%ebx\n"); fprintf(codfp, "\t\tpopl\t%%eax\n"); fprintf(codfp, "\t\tmovl\t%%eax, (%%ebx)\n"); } else fprintf(codfp, "\t\tmovl\t%%eax, %s\n",p->rname);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -