📄 nasm.c
字号:
#include "cmm.h"enum { EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7 };static Symbol charreg[8], shortreg[8], intreg[8];static Symbol quo, rem; /*quo为'/'运算分配的寄存器,rem为'%'分配的寄存器*/static int cseg; /* current segment */static void progbeg(void){ intreg[EAX] = mkreg("eax", EAX); intreg[EDX] = mkreg("edx", EDX); intreg[ECX] = mkreg("ecx", ECX); intreg[EBX] = mkreg("ebx", EBX); intreg[ESI] = mkreg("esi", ESI); intreg[EDI] = mkreg("edi", EDI); shortreg[EAX] = mkreg("ax", EAX); shortreg[ECX] = mkreg("cx", ECX); shortreg[EDX] = mkreg("dx", EDX); shortreg[EBX] = mkreg("bx", EBX); shortreg[ESI] = mkreg("si", ESI); shortreg[EDI] = mkreg("di", EDI); charreg[EAX] = mkreg("al", EAX); charreg[ECX] = mkreg("cl", ECX); charreg[EDX] = mkreg("dl", EDX); charreg[EBX] = mkreg("bl", EBX); rmap[C] = mkwildcard(charreg); rmap[P] = rmap[U] = rmap[I] = rmap[A] = mkwildcard(intreg); quo = mkreg("eax", EAX); quo->x.regnode->mask |= 1<<EDX; rem = mkreg("edx", EDX); rem->x.regnode->mask |= 1<<EAX;}static void emit2(Node p){#define preg(f) ((f)[getregnum(p->kids[0])]->x.name) if (p->op == CVCI) print("movsx %s,%s\n", p->syms[RX]->x.name , preg(charreg)); else if (p->op == CVIC ) { char *dst = shortreg[getregnum(p)]->x.name; char *src = preg(shortreg); if (dst != src) print("mov %s,%s\n", dst, src); }}static void function(Symbol f, Symbol caller[], Symbol callee[]){ int i; DEBUG(fprint(2,"function define start\n")); print("%s:\n", f->x.name); print("push ebx\n"); print("push edx\n"); print("push ecx\n"); print("push esi\n"); print("push edi\n"); print("push ebp\n"); print("mov ebp,esp\n"); freemask = ~(unsigned)0; reg_var_count = 0; offset = 24 + 4; for (i = 0; callee[i]; i++) { Symbol p = callee[i]; Symbol q = caller[i]; assert(q); p->x.offset = q->x.offset = offset; p->x.name = q->x.name = stringf("%d", p->x.offset); p->sclass = q->sclass = AUTO; offset += roundup(q->type->size, 4); } assert(caller[i] == 0); offset = maxoffset = 0; gencode(caller, callee); print("mov esp,ebp\n"); print("pop ebp\n"); print("pop edi\n"); print("pop esi\n"); print("pop ecx\n"); print("pop edx\n"); print("pop ebx\n"); print("ret\n"); DEBUG(fprint(2,"function define end\n"));}static void progend(){}static void defsymbol(Symbol p){ if (p->generated) p->x.name = stringf("L%s", p->name); else if (p->scope == CONSTANT && isptr(p->type)) p->x.name = stringf("%d", p->u.c.v.u); else p->x.name = p->name;}/*target为p选择寄存器*/static void target(Node p){ assert(p); switch(p->op) { case DIVI: /*商在eax,余数在edx,*/ setreg(p, quo); rtarget(p, 0, intreg[EAX]); /*被除数放在eax*/ rtarget(p, 1, intreg[ECX]); /*除数放在ecx*/ break; case MODI: setreg(p, rem); rtarget(p, 0, intreg[EAX]); rtarget(p, 1, intreg[ECX]); break; case ASGNA: /*局部数组的初始化时生成的赋值,将通过movsb指令进行实现*/ setreg(p, intreg[ECX]); /*ecx做为传送数据的计数器*/ rtarget(p, 0, intreg[EDI]); /*edi做为目标寄存器*/ rtarget(p, 1, intreg[ESI]); /*esi做为源寄存器*/ break; case CALLI: case CALLV: case CALL + P: setreg(p, intreg[EAX]); /*函数的返回值放在eax*/ break; case RETI: rtarget(p, 0, intreg[EAX]); /*返回值放在eax*/ break; }}static void doarg(Node p){ assert(p && p->syms[0]); mkactual(4, p->syms[0]->u.c.v.i);}static void segment(int n);static void import(Symbol p){ int oldseg = cseg; if (p->ref > 0) { segment(CODE); print("extern %s\n", p->x.name); segment(oldseg); }}static void space(int n){ if (cseg != BSS) print("resb %d \n", n);}static void segment(int n){ if (n == cseg) return; cseg = n; if (CODE == cseg) print("section .text\n"); else if (DATA == cseg || BSS == cseg) print("section .data\n");}static void local(Symbol p){ if (0 == askregvar(p, rmap[ttob(p->type)])) mkauto(p);}static void global(Symbol p){ print("align %d\n", p->type->align > 4 ? 4 : p->type->align); print("%s:\n", p->x.name); if (BSS == p->u.seg) print("resb %d\n", p->type->size);}static void defconst(int ty,Value v){ switch (ty) { case C: print("db %d\n", v.c); return; case I: print("dd %d\n", v.i ); return; case P: print("dd 0%xH\n", v.p ); return; } assert(0);}/*def_array_end:设置字符数组结束的标志'\0'*/void def_array_end(void){ Value v; v.c = 0; defconst(C, v);}void set_eax(Node p){ p->syms[RX] = intreg[EAX];}void set_edx(Node p){ p->syms[RX] = intreg[EDX];}void put_eax(void){ freemask |= intreg[EAX]->x.regnode->mask;}/*putreg:释放寄存器*/void putreg(Symbol r){ if (r == quo) /*edx已经在之前被释放*/ r = intreg[EAX]; if (r == rem) /*edx已经在之前被释放*/ r = intreg[EDX]; freemask |= r->x.regnode->mask; }void put_edx(void){ freemask |= intreg[EDX]->x.regnode->mask;}int equal_reg(Node p, Node kid){ assert(p && kid); Symbol ra = p->syms[RX], rb = kid->syms[RX]; if (ra == rb) return 1; if ((ra == quo || ra == intreg[EAX]) && (rb == quo || rb == intreg[EAX])) return 1; if ((ra == rem || ra == intreg[EDX]) && (rb == rem || rb == intreg[EDX])) return 1; return 0;}static void defstring(int n, char *str){ char *s; for (s = str; s < str + n; s++) print("db %d\n", (*s)&0377); print("db 0\n");}static void defaddress(Symbol p){ print("dd %s\n", p->x.name);}/*export引出全局的变量*/static void export(Symbol p){ print("global %s\n",p->x.name);}Interface x86IR = { blockbeg, blockend, defaddress, defconst, defstring, defsymbol, export, function, gen, global, import, local, progbeg, progend, segment, space, { emit2, doarg, target, }};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -