📄 disasm-ia32.cc.svn-base
字号:
case NO_INSTR: processed = false; break; default: UNIMPLEMENTED(); // This type is not implemented. } //---------------------------- if (!processed) { switch (*data) { case 0xC2: AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data+1)); data += 3; break; case 0x69: // fall through case 0x6B: { int mod, regop, rm; get_modrm(*(data+1), &mod, ®op, &rm); int32_t imm = *data == 0x6B ? *(data+2) : *reinterpret_cast<int32_t*>(data+2); AppendToBuffer("imul %s,%s,0x%x", NameOfCPURegister(regop), NameOfCPURegister(rm), imm); data += 2 + (*data == 0x6B ? 1 : 4); } break; case 0xF6: { int mod, regop, rm; get_modrm(*(data+1), &mod, ®op, &rm); if (mod == 3 && regop == eax) { AppendToBuffer("test_b %s,%d", NameOfCPURegister(rm), *(data+2)); } else { UnimplementedInstruction(); } data += 3; } break; case 0x81: // fall through case 0x83: // 0x81 with sign extension bit set data += PrintImmediateOp(data); break; case 0x0F: { byte f0byte = *(data+1); const char* f0mnem = F0Mnem(f0byte); if (f0byte == 0xA2 || f0byte == 0x31) { AppendToBuffer("%s", f0mnem); data += 2; } else if ((f0byte & 0xF0) == 0x80) { data += JumpConditional(data, branch_hint); } else if (f0byte == 0xBE || f0byte == 0xBF || f0byte == 0xB6 || f0byte == 0xB7 || f0byte == 0xAF) { data += 2; data += PrintOperands(f0mnem, REG_OPER_OP_ORDER, data); } else { data += 2; if (f0byte == 0xAB || f0byte == 0xA5 || f0byte == 0xAD) { // shrd, shld, bts AppendToBuffer("%s ", f0mnem); int mod, regop, rm; get_modrm(*data, &mod, ®op, &rm); data += PrintRightOperand(data); if (f0byte == 0xAB) { AppendToBuffer(",%s", NameOfCPURegister(regop)); } else { AppendToBuffer(",%s,cl", NameOfCPURegister(regop)); } } else { UnimplementedInstruction(); } } } break; case 0x8F: { data++; int mod, regop, rm; get_modrm(*data, &mod, ®op, &rm); if (regop == eax) { AppendToBuffer("pop "); data += PrintRightOperand(data); } } break; case 0xFF: { data++; int mod, regop, rm; get_modrm(*data, &mod, ®op, &rm); const char* mnem = NULL; switch (regop) { case esi: mnem = "push"; break; case eax: mnem = "inc"; break; case edx: mnem = "call"; break; case esp: mnem = "jmp"; break; default: mnem = "???"; } AppendToBuffer("%s ", mnem); data += PrintRightOperand(data); } break; case 0xC7: // imm32, fall through case 0xC6: // imm8 { bool is_byte = *data == 0xC6; data++; AppendToBuffer("%s ", is_byte ? "mov_b" : "mov"); data += PrintRightOperand(data); int32_t imm = is_byte ? *data : *reinterpret_cast<int32_t*>(data); AppendToBuffer(",0x%x", imm); data += is_byte ? 1 : 4; } break; case 0x88: // 8bit, fall through case 0x89: // 32bit { bool is_byte = *data == 0x88; int mod, regop, rm; data++; get_modrm(*data, &mod, ®op, &rm); AppendToBuffer("%s ", is_byte ? "mov_b" : "mov"); data += PrintRightOperand(data); AppendToBuffer(",%s", NameOfCPURegister(regop)); } break; case 0x66: // prefix data++; if (*data == 0x8B) { data++; data += PrintOperands("mov_w", REG_OPER_OP_ORDER, data); } else if (*data == 0x89) { data++; int mod, regop, rm; get_modrm(*data, &mod, ®op, &rm); AppendToBuffer("mov_w "); data += PrintRightOperand(data); AppendToBuffer(",%s", NameOfCPURegister(regop)); } else { UnimplementedInstruction(); } break; case 0xFE: { data++; int mod, regop, rm; get_modrm(*data, &mod, ®op, &rm); if (mod == 3 && regop == ecx) { AppendToBuffer("dec_b %s", NameOfCPURegister(rm)); } else { UnimplementedInstruction(); } data++; } break; case 0x68: AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data+1)); data += 5; break; case 0x6A: AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1)); data += 2; break; case 0xA8: AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data+1)); data += 2; break; case 0xA9: AppendToBuffer("test eax,0x%x", *reinterpret_cast<int32_t*>(data+1)); data += 5; break; case 0xD1: // fall through case 0xD3: // fall through case 0xC1: data += D1D3C1Instruction(data); break; case 0xD9: // fall through case 0xDA: // fall through case 0xDB: // fall through case 0xDC: // fall through case 0xDD: // fall through case 0xDE: // fall through case 0xDF: data += FPUInstruction(data); break; case 0xEB: data += JumpShort(data); break; case 0xF2: if (*(data+1) == 0x0F) { byte b2 = *(data+2); if (b2 == 0x11) { AppendToBuffer("movsd "); data += 3; int mod, regop, rm; get_modrm(*data, &mod, ®op, &rm); data += PrintRightOperand(data); AppendToBuffer(",%s", NameOfXMMRegister(regop)); } else if (b2 == 0x10) { data += 3; int mod, regop, rm; get_modrm(*data, &mod, ®op, &rm); AppendToBuffer("movsd %s,", NameOfXMMRegister(regop)); data += PrintRightOperand(data); } else { const char* mnem = "?"; switch (b2) { case 0x2A: mnem = "cvtsi2sd"; break; case 0x58: mnem = "addsd"; break; case 0x59: mnem = "mulsd"; break; case 0x5C: mnem = "subsd"; break; case 0x5E: mnem = "divsd"; break; } data += 3; int mod, regop, rm; get_modrm(*data, &mod, ®op, &rm); if (b2 == 0x2A) { AppendToBuffer("%s %s,", mnem, NameOfXMMRegister(regop)); data += PrintRightOperand(data); } else { AppendToBuffer("%s %s,%s", mnem, NameOfXMMRegister(regop), NameOfXMMRegister(rm)); data++; } } } else { UnimplementedInstruction(); } break; case 0xF3: if (*(data+1) == 0x0F && *(data+2) == 0x2C) { data += 3; data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data); } else { UnimplementedInstruction(); } break; case 0xF7: data += F7Instruction(data); break; default: UnimplementedInstruction(); } } if (tmp_buffer_pos_ < sizeof tmp_buffer_) { tmp_buffer_[tmp_buffer_pos_] = '\0'; } int instr_len = data - instr; ASSERT(instr_len > 0); // Ensure progress. int outp = 0; // Instruction bytes. for (byte* bp = instr; bp < data; bp++) { outp += v8::internal::OS::SNPrintF(out_buffer + outp, "%02x", *bp); } for (int i = 6 - instr_len; i >= 0; i--) { outp += v8::internal::OS::SNPrintF(out_buffer + outp, " "); } outp += v8::internal::OS::SNPrintF(out_buffer + outp, " %s", tmp_buffer_.start()); return instr_len;}//------------------------------------------------------------------------------static const char* cpu_regs[8] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",};static const char* xmm_regs[8] = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",};const char* NameConverter::NameOfAddress(byte* addr) const { static v8::internal::EmbeddedVector<char, 32> tmp_buffer; v8::internal::OS::SNPrintF(tmp_buffer, "%p", addr); return tmp_buffer.start();}const char* NameConverter::NameOfConstant(byte* addr) const { return NameOfAddress(addr);}const char* NameConverter::NameOfCPURegister(int reg) const { if (0 <= reg && reg < 8) return cpu_regs[reg]; return "noreg";}const char* NameConverter::NameOfXMMRegister(int reg) const { if (0 <= reg && reg < 8) return xmm_regs[reg]; return "noxmmreg";}const char* NameConverter::NameInCode(byte* addr) const { // IA32 does not embed debug strings at the moment. UNREACHABLE(); return "";}//------------------------------------------------------------------------------static NameConverter defaultConverter;Disassembler::Disassembler() : converter_(defaultConverter) {}Disassembler::Disassembler(const NameConverter& converter) : converter_(converter) {}Disassembler::~Disassembler() {}int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction) { DisassemblerIA32 d(converter_, false /*do not crash if unimplemented*/); return d.InstructionDecode(buffer, instruction);}// The IA-32 assembler does not currently use constant pools.int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; }/*static*/ void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { Disassembler d; for (byte* pc = begin; pc < end;) { v8::internal::EmbeddedVector<char, 128> buffer; buffer[0] = '\0'; byte* prev_pc = pc; pc += d.InstructionDecode(buffer, pc); fprintf(f, "%p", prev_pc); fprintf(f, " "); for (byte* bp = prev_pc; bp < pc; bp++) { fprintf(f, "%02x", *bp); } for (int i = 6 - (pc - prev_pc); i >= 0; i--) { fprintf(f, " "); } fprintf(f, " %s\n", buffer.start()); }}} // namespace disasm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -