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

📄 disasm-ia32.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
        AppendToBuffer("[%s+0x%x]", NameOfCPURegister(rm), disp);        return mod == 2 ? 5 : 2;      }      break;    case 3:      AppendToBuffer("%s", NameOfCPURegister(rm));      return 1;    default:      UnimplementedInstruction();      return 1;  }  UNREACHABLE();}// Returns number of bytes used including the current *data.// Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'.int DisassemblerIA32::PrintOperands(const char* mnem,                                    OperandOrder op_order,                                    byte* data) {  byte modrm = *data;  int mod, regop, rm;  get_modrm(modrm, &mod, &regop, &rm);  int advance = 0;  switch (op_order) {    case REG_OPER_OP_ORDER: {      AppendToBuffer("%s %s,", mnem, NameOfCPURegister(regop));      advance = PrintRightOperand(data);      break;    }    case OPER_REG_OP_ORDER: {      AppendToBuffer("%s ", mnem);      advance = PrintRightOperand(data);      AppendToBuffer(",%s", NameOfCPURegister(regop));      break;    }    default:      UNREACHABLE();      break;  }  return advance;}// Returns number of bytes used by machine instruction, including *data byte.// Writes immediate instructions to 'tmp_buffer_'.int DisassemblerIA32::PrintImmediateOp(byte* data) {  bool sign_extension_bit = (*data & 0x02) != 0;  byte modrm = *(data+1);  int mod, regop, rm;  get_modrm(modrm, &mod, &regop, &rm);  const char* mnem = "Imm???";  switch (regop) {    case 0: mnem = "add"; break;    case 1: mnem = "or"; break;    case 2: mnem = "adc"; break;    case 4: mnem = "and"; break;    case 5: mnem = "sub"; break;    case 6: mnem = "xor"; break;    case 7: mnem = "cmp"; break;    default: UnimplementedInstruction();  }  AppendToBuffer("%s ", mnem);  int count = PrintRightOperand(data+1);  if (sign_extension_bit) {    AppendToBuffer(",0x%x", *(data + 1 + count));    return 1 + count + 1 /*int8*/;  } else {    AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + 1 + count));    return 1 + count + 4 /*int32_t*/;  }}// Returns number of bytes used, including *data.int DisassemblerIA32::F7Instruction(byte* data) {  assert(*data == 0xF7);  byte modrm = *(data+1);  int mod, regop, rm;  get_modrm(modrm, &mod, &regop, &rm);  if (mod == 3 && regop != 0) {    const char* mnem = NULL;    switch (regop) {      case 2: mnem = "not"; break;      case 3: mnem = "neg"; break;      case 4: mnem = "mul"; break;      case 7: mnem = "idiv"; break;      default: UnimplementedInstruction();    }    AppendToBuffer("%s %s", mnem, NameOfCPURegister(rm));    return 2;  } else if (mod == 3 && regop == eax) {    int32_t imm = *reinterpret_cast<int32_t*>(data+2);    AppendToBuffer("test %s,0x%x", NameOfCPURegister(rm), imm);    return 6;  } else if (regop == eax) {    AppendToBuffer("test ");    int count = PrintRightOperand(data+1);    int32_t imm = *reinterpret_cast<int32_t*>(data+1+count);    AppendToBuffer(",0x%x", imm);    return 1+count+4 /*int32_t*/;  } else {    UnimplementedInstruction();    return 2;  }}int DisassemblerIA32::D1D3C1Instruction(byte* data) {  byte op = *data;  assert(op == 0xD1 || op == 0xD3 || op == 0xC1);  byte modrm = *(data+1);  int mod, regop, rm;  get_modrm(modrm, &mod, &regop, &rm);  int imm8 = -1;  int num_bytes = 2;  if (mod == 3) {    const char* mnem = NULL;    if (op == 0xD1) {      imm8 = 1;      switch (regop) {        case edx: mnem = "rcl"; break;        case edi: mnem = "sar"; break;        case esp: mnem = "shl"; break;        default: UnimplementedInstruction();      }    } else if (op == 0xC1) {      imm8 = *(data+2);      num_bytes = 3;      switch (regop) {        case edx: mnem = "rcl"; break;        case esp: mnem = "shl"; break;        case ebp: mnem = "shr"; break;        case edi: mnem = "sar"; break;        default: UnimplementedInstruction();      }    } else if (op == 0xD3) {      switch (regop) {        case esp: mnem = "shl"; break;        case ebp: mnem = "shr"; break;        case edi: mnem = "sar"; break;        default: UnimplementedInstruction();      }    }    assert(mnem != NULL);    AppendToBuffer("%s %s,", mnem, NameOfCPURegister(rm));    if (imm8 > 0) {      AppendToBuffer("%d", imm8);    } else {      AppendToBuffer("cl");    }  } else {    UnimplementedInstruction();  }  return num_bytes;}// Returns number of bytes used, including *data.int DisassemblerIA32::JumpShort(byte* data) {  assert(*data == 0xEB);  byte b = *(data+1);  byte* dest = data + static_cast<int8_t>(b) + 2;  AppendToBuffer("jmp %s", NameOfAddress(dest));  return 2;}// Returns number of bytes used, including *data.int DisassemblerIA32::JumpConditional(byte* data, const char* comment) {  assert(*data == 0x0F);  byte cond = *(data+1) & 0x0F;  byte* dest = data + *reinterpret_cast<int32_t*>(data+2) + 6;  const char* mnem = jump_conditional_mnem[cond];  AppendToBuffer("%s %s", mnem, NameOfAddress(dest));  if (comment != NULL) {    AppendToBuffer(", %s", comment);  }  return 6;  // includes 0x0F}// Returns number of bytes used, including *data.int DisassemblerIA32::JumpConditionalShort(byte* data, const char* comment) {  byte cond = *data & 0x0F;  byte b = *(data+1);  byte* dest = data + static_cast<int8_t>(b) + 2;  const char* mnem = jump_conditional_mnem[cond];  AppendToBuffer("%s %s", mnem, NameOfAddress(dest));  if (comment != NULL) {    AppendToBuffer(", %s", comment);  }  return 2;}// Returns number of bytes used, including *data.int DisassemblerIA32::FPUInstruction(byte* data) {  byte b1 = *data;  byte b2 = *(data + 1);  if (b1 == 0xD9) {    const char* mnem = NULL;    switch (b2) {      case 0xE8: mnem = "fld1"; break;      case 0xEE: mnem = "fldz"; break;      case 0xE1: mnem = "fabs"; break;      case 0xE0: mnem = "fchs"; break;      case 0xF8: mnem = "fprem"; break;      case 0xF5: mnem = "fprem1"; break;      case 0xF7: mnem = "fincstp"; break;      case 0xE4: mnem = "ftst"; break;    }    if (mnem != NULL) {      AppendToBuffer("%s", mnem);      return 2;    } else if ((b2 & 0xF8) == 0xC8) {      AppendToBuffer("fxch st%d", b2 & 0x7);      return 2;    } else {      int mod, regop, rm;      get_modrm(*(data+1), &mod, &regop, &rm);      const char* mnem = "?";      switch (regop) {        case eax: mnem = "fld_s"; break;        case ebx: mnem = "fstp_s"; break;        default: UnimplementedInstruction();      }      AppendToBuffer("%s ", mnem);      int count = PrintRightOperand(data + 1);      return count + 1;    }  } else if (b1 == 0xDD) {    if ((b2 & 0xF8) == 0xC0) {      AppendToBuffer("ffree st%d", b2 & 0x7);      return 2;    } else {      int mod, regop, rm;      get_modrm(*(data+1), &mod, &regop, &rm);      const char* mnem = "?";      switch (regop) {        case eax: mnem = "fld_d"; break;        case ebx: mnem = "fstp_d"; break;        default: UnimplementedInstruction();      }      AppendToBuffer("%s ", mnem);      int count = PrintRightOperand(data + 1);      return count + 1;    }  } else if (b1 == 0xDB) {    int mod, regop, rm;    get_modrm(*(data+1), &mod, &regop, &rm);    const char* mnem = "?";    switch (regop) {      case eax: mnem = "fild_s"; break;      case edx: mnem = "fist_s"; break;      case ebx: mnem = "fistp_s"; break;      default: UnimplementedInstruction();    }    AppendToBuffer("%s ", mnem);    int count = PrintRightOperand(data + 1);    return count + 1;  } else if (b1 == 0xDF) {    if (b2 == 0xE0) {      AppendToBuffer("fnstsw_ax");      return 2;    }    int mod, regop, rm;    get_modrm(*(data+1), &mod, &regop, &rm);    const char* mnem = "?";    switch (regop) {      case ebp: mnem = "fild_d"; break;      case edi: mnem = "fistp_d"; break;      default: UnimplementedInstruction();    }    AppendToBuffer("%s ", mnem);    int count = PrintRightOperand(data + 1);    return count + 1;  } else if (b1 == 0xDC || b1 == 0xDE) {    bool is_pop = (b1 == 0xDE);    if (is_pop && b2 == 0xD9) {      AppendToBuffer("fcompp");      return 2;    }    const char* mnem = "FP0xDC";    switch (b2 & 0xF8) {      case 0xC0: mnem = "fadd"; break;      case 0xE8: mnem = "fsub"; break;      case 0xC8: mnem = "fmul"; break;      case 0xF8: mnem = "fdiv"; break;      default: UnimplementedInstruction();    }    AppendToBuffer("%s%s st%d", mnem, is_pop ? "p" : "", b2 & 0x7);    return 2;  } else if (b1 == 0xDA && b2 == 0xE9) {    const char* mnem = "fucompp";    AppendToBuffer("%s", mnem);    return 2;  }  AppendToBuffer("Unknown FP instruction");  return 2;}// Mnemonics for instructions 0xF0 byte.// Returns NULL if the instruction is not handled here.static const char* F0Mnem(byte f0byte) {  switch (f0byte) {    case 0xA2: return "cpuid";    case 0x31: return "rdtsc";    case 0xBE: return "movsx_b";    case 0xBF: return "movsx_w";    case 0xB6: return "movzx_b";    case 0xB7: return "movzx_w";    case 0xAF: return "imul";    case 0xA5: return "shld";    case 0xAD: return "shrd";    case 0xAB: return "bts";    default: return NULL;  }}// Disassembled instruction '*instr' and writes it intro 'out_buffer'.int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,                                        byte* instr) {  tmp_buffer_pos_ = 0;  // starting to write as position 0  byte* data = instr;  // Check for hints.  const char* branch_hint = NULL;  // We use this two prefixes only with branch prediction  if (*data == 0x3E /*ds*/) {    branch_hint = "predicted taken";    data++;  } else if (*data == 0x2E /*cs*/) {    branch_hint = "predicted not taken";    data++;  }  bool processed = true;  // Will be set to false if the current instruction                          // is not in 'instructions' table.  const InstructionDesc& idesc = instruction_table.Get(*data);  switch (idesc.type) {    case ZERO_OPERANDS_INSTR:      AppendToBuffer(idesc.mnem);      data++;      break;    case TWO_OPERANDS_INSTR:      data++;      data += PrintOperands(idesc.mnem, idesc.op_order_, data);      break;    case JUMP_CONDITIONAL_SHORT_INSTR:      data += JumpConditionalShort(data, branch_hint);      break;    case REGISTER_INSTR:      AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));      data++;      break;    case MOVE_REG_INSTR: {      byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));      AppendToBuffer("mov %s,%s",                     NameOfCPURegister(*data & 0x07),                     NameOfAddress(addr));      data += 5;      break;    }    case CALL_JUMP_INSTR: {      byte* addr = data + *reinterpret_cast<int32_t*>(data+1) + 5;      AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr));      data += 5;      break;    }    case SHORT_IMMEDIATE_INSTR: {      byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));      AppendToBuffer("%s eax, %s", idesc.mnem, NameOfAddress(addr));      data += 5;      break;    }

⌨️ 快捷键说明

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