⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disassembler.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
  case sh_op:  case sw_op:  case sd_op:  case swl_op:  case swr_op:  case lwl_op:  case lwr_op:  case ll_op:  case sc_op:    sprintf(bufptr, "%s\t%s,", op_name[i.i_format.opcode],	    register_name(i.i_format.rt, regmask));    do_loadstore = true;    break;      case ori_op:  case xori_op:    if (i.u_format.rs == ZERO) {      sprintf(bufptr, "li\t%s,%d",	      register_name(i.u_format.rt, regmask),	      i.u_format.uimmediate);      break;    }    /* fall through */  case andi_op:    sprintf(bufptr, "%s\t%s,%s,%#x", op_name[i.u_format.opcode],	    register_name(i.u_format.rt, regmask),	    register_name(i.u_format.rs, regmask),	    i.u_format.uimmediate);    break;  case lui_op:    sprintf(bufptr, "%s\t%s,%#x", op_name[i.u_format.opcode],	    register_name(i.u_format.rt, regmask),	    i.u_format.uimmediate);    break;  case addi_op:  case addiu_op:    if (i.i_format.rs == ZERO) {      short sign_extender = i.i_format.simmediate;      sprintf(bufptr, "li\t%s,%d",	      register_name(i.i_format.rt, regmask),	      sign_extender);      break;    }    /* fall through */  default:    {      short sign_extender = i.i_format.simmediate;      sprintf(bufptr, "%s\t%s,%s,%d", op_name[i.i_format.opcode],	      register_name(i.i_format.rt, regmask),	      register_name(i.i_format.rs, regmask),	      sign_extender);    }    break;  case cop0_op:    switch (i.r_format.rs) {    case bc_op:      sprintf(bufptr, "bc0%s\t", bc_name[i.i_format.rt]);      do_b_displacement = true;      break;    case mtc_op:      sprintf(bufptr, "mtc0\t%s,%s",	      register_name(i.r_format.rt, regmask),	      c0_register_name(i.r_format.rd));      break;    case mfc_op:      sprintf(bufptr, "mfc0\t%s,%s",	      register_name(i.r_format.rt, regmask),	      c0_register_name(i.r_format.rd));      break;    case cfc_op:      sprintf(bufptr, "cfc0\t%s,$%d",	      register_name(i.r_format.rt, regmask),	      i.r_format.rd);      break;    case ctc_op:      sprintf(bufptr, "ctc0\t%s,$%d",	      register_name(i.r_format.rt, regmask),	      i.r_format.rd);      break;    case cop_op:      sprintf(bufptr, "c0\t%s", c0func_name[i.r_format.func]);      break;    default:      sprintf(bufptr, "c0rs%d", i.r_format.rs);      break;    }    break;      case cop1_op:    switch (i.r_format.rs) {    case bc_op:      sprintf(bufptr, "bc1%s\t", bc_name[i.i_format.rt]);      do_b_displacement = true;      break;    case mtc_op:      sprintf(bufptr, "mtc1\t%s,%s",	      register_name(i.r_format.rt, regmask),	      fp_register_name(i.r_format.rd));      break;    case mfc_op:      sprintf(bufptr, "mfc1\t%s,%s",	      register_name(i.r_format.rt, regmask),	      fp_register_name(i.r_format.rd));      break;    case cfc_op:      sprintf(bufptr, "cfc1\t%s,$%d",	      register_name(i.r_format.rt, regmask),	      i.r_format.rd);      break;    case ctc_op:      sprintf(bufptr, "ctc1\t%s,$%d",	      register_name(i.r_format.rt, regmask),	      i.r_format.rd);      break;    case cop_op+s_fmt:    case cop_op+d_fmt:    case cop_op+e_fmt:    case cop_op+w_fmt:      sprintf(bufptr, "%s.%s\t",	      cop1func_name[i.r_format.func],	      c1fmt_name[i.r_format.rs - cop_op]);      bufptr += strlen(bufptr);      switch (i.r_format.func) {      case fsqrt_op:      case fabs_op:      case fmov_op:      case fcvts_op:      case fcvtd_op:      case fcvte_op:      case fcvtw_op:      case ftrunc_op:      case fround_op:      case ffloor_op:      case fceil_op:	sprintf(bufptr, "%s,%s",		fp_register_name(i.r_format.re),		fp_register_name(i.r_format.rd));	break;      case fcmp_op+0x0:      case fcmp_op+0x1:      case fcmp_op+0x2:      case fcmp_op+0x3:      case fcmp_op+0x4:      case fcmp_op+0x5:      case fcmp_op+0x6:      case fcmp_op+0x7:      case fcmp_op+0x8:      case fcmp_op+0x9:      case fcmp_op+0xa:      case fcmp_op+0xb:      case fcmp_op+0xc:      case fcmp_op+0xd:      case fcmp_op+0xe:      case fcmp_op+0xf:	sprintf(bufptr, "%s,%s",		fp_register_name(i.r_format.rd),		fp_register_name(i.r_format.rt));	break;      default:	sprintf(bufptr, "%s,%s,%s",		fp_register_name(i.r_format.re),		fp_register_name(i.r_format.rd),		fp_register_name(i.r_format.rt));	break;      } /* switch on func */    } /* switch on rs */    break; /* End of cop1 */      case cop2_op:  case cop3_op:    {      unsigned which_cop = i.j_format.opcode - cop0_op;            switch (i.r_format.rs) {      case bc_op:	sprintf(bufptr, "bc%d%c\t", which_cop,		bc_name[i.r_format.rt]);	do_b_displacement = true;	break;      case mtc_op:	sprintf(bufptr, "mtc%d\t%s,$%d", which_cop,		register_name(i.r_format.rt, regmask),		i.r_format.rd);	break;      case mfc_op:	sprintf(bufptr, "mfc%d\t%s,$%d", which_cop,		register_name(i.r_format.rt, regmask),		i.r_format.rd);	break;      case cfc_op:	sprintf(bufptr, "cfc%d\t%s,$%d", which_cop,		register_name(i.r_format.rt, regmask),		i.r_format.rd);	break;      case ctc_op:	sprintf(bufptr, "ctc%d\t%s,$%d", which_cop,		register_name(i.r_format.rt, regmask),		i.r_format.rd);	break;      default:	sprintf(bufptr, "c%d.%d\t%d", which_cop, i.r_format.rs, i.r_format.func);	break;      }    }    break;      }    /* Some instructions require more than just registers */    if (do_loadstore) {    short sign_extender = i.i_format.simmediate;    *symbol_value = sign_extender;    *ls_register = i.i_format.rs;    bufptr += strlen(bufptr);    sprintf(bufptr, "%d(%s)", sign_extender,	    register_name(i.i_format.rs, regmask));    return_value = -1;  }  else if (do_b_displacement) {    short sign_extender = i.i_format.simmediate;    bufptr += strlen(bufptr);    sprintf(bufptr, "%#x", address+4+(sign_extender<<2));    return_value = 2;  }    return return_value;}/* public - see .h file */voiddis_regs(buffer, regmask, reg_values)  char *buffer;  unsigned regmask;  unsigned reg_values[];  {  boolean first = true;  unsigned i;  buffer += strlen(buffer);  for (i = 0; regmask; i++, regmask >>= 1)    {    if (regmask & 1)      {      sprintf(buffer, "%s%s=%#x",	first ? "\t<" : ",",	save.reg_names[i],	reg_values[i]);      buffer += strlen(buffer);      first = false;      }    }  if (!first)    strcat(buffer, ">");  }#include <errno.h>extern int errno;/* public - see .h file */intdisassembler(iadr, regstyle, get_symname, get_regvalue, get_bytes, print_header)  unsigned iadr;  int regstyle;  char *(*get_symname)();  int (*get_regvalue)();  long (*get_bytes)();  void (*print_header)();  {  unsigned old_iadr = iadr;  if (!get_bytes)    {    errno = EINVAL;    return -1;    }  /* Don't print address, value, or (if we have get_symname) jal targets */  dis_init("", "", regstyle ? HARDWARE_NAMES : COMPILER_NAMES,    ! (int) get_symname);  for (; ; iadr += 4)    {    int which;    unsigned instr, regmask, symbol_value, ls_register;    char buffer[1024], *symname;    instr = (unsigned) get_bytes();    if (print_header)      print_header(iadr, instr);    which = disasm(buffer, iadr, instr, &regmask, &symbol_value, &ls_register);    /* For jal, must print the target either via get_symname or numerically */    if ((which == 1) && get_symname)      if (symname = get_symname(symbol_value))	strcat(buffer, symname);      else	sprintf(buffer + strlen(buffer), "%#x", symbol_value);    /* For load/store, if we have get_regvalue, must print the effective addr */    else if ((which < 0) && get_regvalue)      sprintf(buffer + strlen(buffer),	" <0x%x>", get_regvalue(ls_register) + symbol_value);    /* If we have get_regvalue, we must print the registers */    if (regmask && get_regvalue)      {      unsigned reg_values[32], reg_cnt, regtemp;      for (reg_cnt = 0, regtemp = regmask; regtemp; reg_cnt++, regtemp >>= 1)	if (regtemp & 1)	  reg_values[reg_cnt] = get_regvalue(reg_cnt);      dis_regs(buffer + strlen(buffer), regmask, reg_values);      }    puts(buffer);    /* Quit unless we have a jump/call/branch delay slot */    if (which <= 0)      return iadr - old_iadr + 4;    }  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -