📄 operand.c
字号:
str[i] = *(p+i+1); i++; } } else if (p == s) { /* head */ while (p+i <= q) { str[i] = *(p+i); i++; } } str[i] = 0; o_key_t *okey = (o_key_t *)a64_malloc(sizeof(o_key_t)); /* get operands key word */ if (!ops_key->so_key) { /* this is a source operand */ ops_key->so_key = okey; } else if (!ops_key->do_key) { /* this is a dest operand */ ops_key->do_key = okey; } else if (!ops_key->to_key) { /* this is a three operand */ ops_key->to_key = okey; } else { a64_free(okey); sprintf(tmp_msg, "at %d: %s\n", line, "operands over three"); if (str_len(msg) + str_len(tmp_msg) < ERR_MSG_SIZE) { str_cat(msg, tmp_msg); mount_err_link(0, 0, msg); } else { errno |= ERR_OPERAND; mount_err_link(errno, ops_errmsg, 0); return errno; } } errno |= get_o_key(okey, str); if (p <= s) break; p--; /* search next operand */ } return errno;}/*********************************************************************** function: unsigned int get_attr(o_key_t* o_key); parameter: o_key: a operand key word return value: unsigned int operand attribute wordlast change: 02-17-2006 21:10 by mik***********************************************************************/unsigned int get_attr(o_key_t *o_key){ if (!o_key) return 0; unsigned int o_attr = 0; if (o_key->reg) { o_attr |= 0x80000000 >> (o_key->reg & 0x07); switch (o_key->reg & 0xf0) { case 0x10: case 0x20: case 0x40: case 0x80: o_attr |= GPR | ((o_key->reg & 0xf0) >> 4); break; case 0xa0: o_attr |= SREG | SIZE16; break; case 0xc0: o_attr |= CREG | SIZE32; break; case 0xd0: o_attr |= DREG | SIZE32; break; case 0xe0: o_attr |= MMX | SIZE64; break; case 0xf0: o_attr |= XMM | SIZE128; break; } } else if (o_key->mem) { if (!o_key->mem->base && !o_key->mem->index) { if (o_key->mem->disp) o_attr |= MOFFSET; } else o_attr |= MEM; /* get memory operand size */ /* example: case is 32 chang to SIZE32 = cast >> 3 */ o_attr |= o_key->mem->cast >> 3; } else if (o_key->imme) { /* immediate operand not size */ if (o_key->imme->imme_value == 1) o_attr |= IMME_1; else o_attr |= IMME; unsigned int size = get_sizeof(o_key->imme->imme_value); /****************************** * TODO: reserved for imme size * example: (dword)0x0c ******************************/ if (o_key->imme->cast) { o_attr |= (o_key->imme->cast >> 3); } else { if (size == 1) o_attr |= 0x01; else if (size <= current_bits) { o_attr |= current_bits >> 3; o_key->imme->cast = current_bits; } } } return o_attr;}/************************************************************************ function: errno get_ops_attr(ops_attr_t *ops_attr, ops_key_t *ops_key); parameter: ops_key: operands key words return value: error if errno is set successed if errno is 0last change: 02-17-2006 21:32 by mik************************************************************************/errno_t get_ops_attr(ops_attr_t *ops_attr, ops_key_t *ops_key){ if (!ops_attr) return ERR_OPERAND; if (!ops_key) { /* no operands */ ops_attr->so_attr = 0; ops_attr->do_attr = 0; ops_attr->to_attr = 0; return 0; } /* source operand is immediate. dest operand is register */ if (ops_key->so_key && ops_key->so_key->imme && ops_key->do_key && ops_key->do_key->reg) { if (get_sizeof(ops_key->so_key->imme->imme_value) > ((ops_key->do_key->reg & 0xf0) >> 4)) { mount_err_link(ERR_OPERAND, ops_errmsg, 0); return ERR_OPERAND; } } ops_attr->so_attr = get_attr(ops_key->so_key); ops_attr->do_attr = get_attr(ops_key->do_key); ops_attr->to_attr = get_attr(ops_key->to_key); if (((OPTYPE(ops_attr->so_attr) == MEM) && (OPTYPE(ops_attr->do_attr) == MEM)) || ((OPTYPE(ops_attr->so_attr) == IMME) && (OPTYPE(ops_attr->do_attr) == IMME))) { mount_err_link(ERR_OPERAND, ops_errmsg, 0); return ERR_OPERAND; } return 0;}/************** the function get operands type ************last change: 02-18-2006 12:11 by mik***********************************************************/ops_type_t get_ops_type(ops_key_t *ops_key){ ops_type_t ops_type = 0; if (!ops_key) return 0; o_key_t *so_key = ops_key->so_key; o_key_t *do_key = ops_key->do_key; o_key_t *to_key = ops_key->to_key; /* get source operand type */ if (so_key) ops_type |= so_key->reg ? S_R : so_key->mem ? S_M : so_key->imme ? S_I : 0; /* get dest operand type */ if (do_key) ops_type |= do_key->reg ? D_R : do_key->mem ? D_M : do_key->imme ? D_I : 0; /* get three operand type */ if (to_key) ops_type |= to_key->reg ? T_R : to_key->mem ? T_M : to_key->imme ? T_I : 0; return ops_type;}unsigned int get_o_size(o_key_t *o_key){ unsigned int o_size = 0; if (!o_key) return 0; if (o_key->reg) o_size = get_reg_size(o_key->reg); else if (o_key->mem) o_size = o_key->mem->cast; else if (o_key->imme) { if (o_key->imme->cast) o_size = o_key->imme->cast; else if (o_key->imme->imme_value == 0) o_size = current_bits; else o_size = get_sizeof(o_key->imme->imme_value) * 8; } return o_size;}/*****************************************************************the function get operands sizelast change: 02-17-2006 21:54 by mik******************************************************************/unsigned int get_ops_size(ops_key_t *ops_key){ unsigned int ops_size = 0; if (!ops_key) return 0; o_key_t *so_key = ops_key->so_key; o_key_t *do_key = ops_key->do_key; o_key_t *to_key = ops_key->to_key; if (so_key && !do_key && !to_key) { /* only one operand */ if (so_key->reg) { ops_size = get_reg_size(so_key->reg); } else if (so_key->mem) { /* only one operand case: * the operand size must be casted */ ops_size = so_key->mem->cast; } else if (so_key->imme) { /************************************** * TODO: reserver for check imme size **************************************/ if (so_key->imme->cast) { ops_size = so_key->imme->cast; } else if (so_key->imme->imme_value == 0) { ops_size = current_bits; } else ops_size = get_sizeof(so_key->imme->imme_value) * 8; } } else if (so_key && do_key && !to_key) { /* two operands */ unsigned int reg_size = 0; if (so_key->reg && do_key->reg) { reg_size = get_reg_size(so_key->reg); if (get_reg_size(do_key->reg) > reg_size) reg_size = get_reg_size(do_key->reg); } else if (so_key->reg) reg_size = get_reg_size(so_key->reg); else if (do_key->reg) reg_size = get_reg_size(do_key->reg); unsigned int mem_size = so_key->mem ? so_key->mem->cast : do_key->mem ? do_key->mem->cast : 0; unsigned int imme_size = so_key->imme ? get_sizeof(so_key->imme->imme_value) * 8 : do_key->imme ? get_sizeof(do_key->imme->imme_value) * 8 : 0; if (reg_size) { if ((mem_size > reg_size) || (imme_size > reg_size)) ops_size = 0; else ops_size = reg_size; } else if (mem_size) { if (imme_size > mem_size) ops_size = 0; else ops_size = mem_size; } else ops_size = 0; } else if (so_key && do_key && to_key) { /* three operands */ ops_size = get_reg_size(to_key->reg); } return ops_size;}/******************************************************* the function get operands address size** last change: 02-18-2006 14:40 by mik******************************************************/unsigned int get_ops_addr(ops_key_t *ops_key){ unsigned int addr = 0; if (!ops_key) return 0; mem_t *mem = ops_key->so_key && ops_key->so_key->mem ? ops_key->so_key->mem : ops_key->do_key && ops_key->do_key->mem ? ops_key->do_key->mem : ops_key->to_key && ops_key->to_key->mem ? ops_key->to_key->mem : 0; /* if (mem) { addr = mem->base ? (mem->base & 0xf0) >> 1 : mem->index ? (mem->index & 0xf0) >> 1: mem->disp ? get_sizeof(mem->disp) * 8 : 0; }*/ addr = mem ? mem->addr : 0; return addr;}/********************************************************* * the function check operand valid * * last change: 02-18-2006 14:15 by mik ********************************************************/int check_ops_key(ops_key_t *ops_key){ /* have no operand */ if (!ops_key) return 1; int ops_size = get_ops_size(ops_key); int so_size = get_o_size(ops_key->so_key); int do_size = get_o_size(ops_key->do_key); int to_size = get_o_size(ops_key->to_key); int addr = get_ops_addr(ops_key); o_key_t *so_key = ops_key->so_key; o_key_t *do_key = ops_key->do_key; o_key_t *to_key = ops_key->to_key; if ((ops_size >= 64) && (current_bits != 64)) return 0; if ((addr >= 64) && (current_bits != 64)) return 0; if ((so_key && is_eGPR(so_key->reg)) || (do_key && is_eGPR(do_key->reg)) || (to_key && is_eGPR(to_key->reg))) if (current_bits != 64) return 0; switch (get_ops_type(ops_key)) { case D_R|S_R: if (do_size < so_size) return 0; break; case D_M|S_R: if (do_size && (do_size != so_size)) return 0; break; case T_R|D_R|S_I: /* this case for imul Gv, Ev, Iv */ case T_R|D_M|S_I: case T_M|D_R|S_I: /* this case for shld Ev,Gv,Ib */ if (to_size < do_size) return 0; break; case T_M|D_R|S_R: if (do_size < so_size || to_size < do_size) return 0; break; }#if 0 if (ops_size && (ops_size <= current_bits) && (addr <= current_bits)) { if ((current_bits == 64) && addr && (addr <= 16)) return 0; return 1; } else if ((current_bits == 16) && (ops_size < 64)) return 1; #endif return 1;}/*************************************************** follow for test....***************************************************/void release_o_key(o_key_t *o_key);void release_ops_key(ops_key_t *ops_key) { if (ops_key->so_key) release_o_key(ops_key->so_key); if (ops_key->do_key) release_o_key(ops_key->do_key); if (ops_key->to_key) release_o_key(ops_key->to_key);}void release_o_key(o_key_t *o_key) { if (o_key) { if (o_key->mem) free(o_key->mem); free(o_key); } }/****************************************************************/void print_okey(o_key_t* o_key) { printf("-----------------------------------\n"); printf("reg is %x\n", o_key->reg); printf("imme is %f\n", o_key->imme); union { long long ll; long l[2]; } l; if (o_key->mem) { printf("---base is %x\n", o_key->mem->base); printf("---index is %x\n", o_key->mem->index); printf("---scale is %x\n", o_key->mem->scale); l.ll = o_key->mem->disp; printf("---disp is %x\n", l.l[1]); printf("---disp is %x\n", l.l[0]); printf("---oseg is %x\n", o_key->mem->oseg); printf("---cast is %d\n", o_key->mem->cast); printf("---addr is %d\n", o_key->mem->addr); } printf("-----------------------------------------\n");}void print_ops(ops_key_t *ops) { if (ops) { if (ops->so_key) print_okey(ops->so_key); if (ops->do_key) print_okey(ops->do_key); if (ops->to_key) print_okey(ops->to_key); }// release_ops_key(ops);}void print_ops_attr(ops_attr_t *ops_attr){ printf("so_attr: %x\n", ops_attr->so_attr); printf("do_attr: %x\n", ops_attr->do_attr); printf("to_attr: %x\n", ops_attr->to_attr);}static void print_ekey(e_key_t *e_key){ while (e_key) { print_ops(e_key->ops_key); puts("**************************************"); e_key = e_key->next; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -