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

📄 disasm-ia32.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
// Copyright 2007-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright//       notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above//       copyright notice, this list of conditions and the following//       disclaimer in the documentation and/or other materials provided//       with the distribution.//     * Neither the name of Google Inc. nor the names of its//       contributors may be used to endorse or promote products derived//       from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include <assert.h>#include <stdio.h>#include <stdarg.h>#include "v8.h"#include "disasm.h"namespace disasm {enum OperandOrder {  UNSET_OP_ORDER = 0,  REG_OPER_OP_ORDER,  OPER_REG_OP_ORDER};//------------------------------------------------------------------// Tables//------------------------------------------------------------------struct ByteMnemonic {  int b;  // -1 terminates, otherwise must be in range (0..255)  const char* mnem;  OperandOrder op_order_;};static ByteMnemonic two_operands_instr[] = {  {0x03, "add", REG_OPER_OP_ORDER},  {0x21, "and", OPER_REG_OP_ORDER},  {0x23, "and", REG_OPER_OP_ORDER},  {0x3B, "cmp", REG_OPER_OP_ORDER},  {0x8D, "lea", REG_OPER_OP_ORDER},  {0x09, "or", OPER_REG_OP_ORDER},  {0x0B, "or", REG_OPER_OP_ORDER},  {0x1B, "sbb", REG_OPER_OP_ORDER},  {0x29, "sub", OPER_REG_OP_ORDER},  {0x2B, "sub", REG_OPER_OP_ORDER},  {0x85, "test", REG_OPER_OP_ORDER},  {0x31, "xor", OPER_REG_OP_ORDER},  {0x33, "xor", REG_OPER_OP_ORDER},  {0x8A, "mov_b", REG_OPER_OP_ORDER},  {0x8B, "mov", REG_OPER_OP_ORDER},  {-1, "", UNSET_OP_ORDER}};static ByteMnemonic zero_operands_instr[] = {  {0xC3, "ret", UNSET_OP_ORDER},  {0xC9, "leave", UNSET_OP_ORDER},  {0x90, "nop", UNSET_OP_ORDER},  {0xF4, "hlt", UNSET_OP_ORDER},  {0xCC, "int3", UNSET_OP_ORDER},  {0x60, "pushad", UNSET_OP_ORDER},  {0x61, "popad", UNSET_OP_ORDER},  {0x9C, "pushfd", UNSET_OP_ORDER},  {0x9D, "popfd", UNSET_OP_ORDER},  {0x9E, "sahf", UNSET_OP_ORDER},  {0x99, "cdq", UNSET_OP_ORDER},  {0x9B, "fwait", UNSET_OP_ORDER},  {-1, "", UNSET_OP_ORDER}};static ByteMnemonic call_jump_instr[] = {  {0xE8, "call", UNSET_OP_ORDER},  {0xE9, "jmp", UNSET_OP_ORDER},  {-1, "", UNSET_OP_ORDER}};static ByteMnemonic short_immediate_instr[] = {  {0x05, "add", UNSET_OP_ORDER},  {0x0D, "or", UNSET_OP_ORDER},  {0x15, "adc", UNSET_OP_ORDER},  {0x25, "and", UNSET_OP_ORDER},  {0x2D, "sub", UNSET_OP_ORDER},  {0x35, "xor", UNSET_OP_ORDER},  {0x3D, "cmp", UNSET_OP_ORDER},  {-1, "", UNSET_OP_ORDER}};static const char* jump_conditional_mnem[] = {  /*0*/ "jo", "jno", "jc", "jnc",  /*4*/ "jz", "jnz", "jna", "ja",  /*8*/ "js", "jns", "jpe", "jpo",  /*12*/ "jl", "jnl", "jng", "jg"};enum InstructionType {  NO_INSTR,  ZERO_OPERANDS_INSTR,  TWO_OPERANDS_INSTR,  JUMP_CONDITIONAL_SHORT_INSTR,  REGISTER_INSTR,  MOVE_REG_INSTR,  CALL_JUMP_INSTR,  SHORT_IMMEDIATE_INSTR};struct InstructionDesc {  const char* mnem;  InstructionType type;  OperandOrder op_order_;};class InstructionTable { public:  InstructionTable();  const InstructionDesc& Get(byte x) const { return instructions_[x]; } private:  InstructionDesc instructions_[256];  void Clear();  void Init();  void CopyTable(ByteMnemonic bm[], InstructionType type);  void SetTableRange(InstructionType type,                     byte start,                     byte end,                     const char* mnem);  void AddJumpConditionalShort();};InstructionTable::InstructionTable() {  Clear();  Init();}void InstructionTable::Clear() {  for (int i = 0; i < 256; i++) {    instructions_[i].mnem = "";    instructions_[i].type = NO_INSTR;    instructions_[i].op_order_ = UNSET_OP_ORDER;  }}void InstructionTable::Init() {  CopyTable(two_operands_instr, TWO_OPERANDS_INSTR);  CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR);  CopyTable(call_jump_instr, CALL_JUMP_INSTR);  CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);  AddJumpConditionalShort();  SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc");  SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec");  SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push");  SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop");  SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov");}void InstructionTable::CopyTable(ByteMnemonic bm[], InstructionType type) {  for (int i = 0; bm[i].b >= 0; i++) {    InstructionDesc* id = &instructions_[bm[i].b];    id->mnem = bm[i].mnem;    id->op_order_ = bm[i].op_order_;    assert(id->type == NO_INSTR);  // Information already entered    id->type = type;  }}void InstructionTable::SetTableRange(InstructionType type,                                     byte start,                                     byte end,                                     const char* mnem) {  for (byte b = start; b <= end; b++) {    InstructionDesc* id = &instructions_[b];    assert(id->type == NO_INSTR);  // Information already entered    id->mnem = mnem;    id->type = type;  }}void InstructionTable::AddJumpConditionalShort() {  for (byte b = 0x70; b <= 0x7F; b++) {    InstructionDesc* id = &instructions_[b];    assert(id->type == NO_INSTR);  // Information already entered    id->mnem = jump_conditional_mnem[b & 0x0F];    id->type = JUMP_CONDITIONAL_SHORT_INSTR;  }}static InstructionTable instruction_table;// The IA32 disassembler implementation.class DisassemblerIA32 { public:  DisassemblerIA32(const NameConverter& converter,                   bool abort_on_unimplemented = true)      : converter_(converter),        tmp_buffer_pos_(0),        abort_on_unimplemented_(abort_on_unimplemented) {    tmp_buffer_[0] = '\0';  }  virtual ~DisassemblerIA32() {}  // Writes one disassembled instruction into 'buffer' (0-terminated).  // Returns the length of the disassembled machine instruction in bytes.  int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction); private:  const NameConverter& converter_;  v8::internal::EmbeddedVector<char, 128> tmp_buffer_;  unsigned int tmp_buffer_pos_;  bool abort_on_unimplemented_;  enum {    eax = 0,    ecx = 1,    edx = 2,    ebx = 3,    esp = 4,    ebp = 5,    esi = 6,    edi = 7  };  const char* NameOfCPURegister(int reg) const {    return converter_.NameOfCPURegister(reg);  }  const char* NameOfXMMRegister(int reg) const {    return converter_.NameOfXMMRegister(reg);  }  const char* NameOfAddress(byte* addr) const {    return converter_.NameOfAddress(addr);  }  // Disassembler helper functions.  static void get_modrm(byte data, int* mod, int* regop, int* rm) {    *mod = (data >> 6) & 3;    *regop = (data & 0x38) >> 3;    *rm = data & 7;  }  static void get_sib(byte data, int* scale, int* index, int* base) {    *scale = (data >> 6) & 3;    *index = (data >> 3) & 7;    *base = data & 7;  }  int PrintRightOperand(byte* modrmp);  int PrintOperands(const char* mnem, OperandOrder op_order, byte* data);  int PrintImmediateOp(byte* data);  int F7Instruction(byte* data);  int D1D3C1Instruction(byte* data);  int JumpShort(byte* data);  int JumpConditional(byte* data, const char* comment);  int JumpConditionalShort(byte* data, const char* comment);  int FPUInstruction(byte* data);  void AppendToBuffer(const char* format, ...);  void UnimplementedInstruction() {    if (abort_on_unimplemented_) {      UNIMPLEMENTED();    } else {      AppendToBuffer("'Unimplemented Instruction'");    }  }};void DisassemblerIA32::AppendToBuffer(const char* format, ...) {  v8::internal::Vector<char> buf = tmp_buffer_ + tmp_buffer_pos_;  va_list args;  va_start(args, format);  int result = v8::internal::OS::VSNPrintF(buf, format, args);  va_end(args);  tmp_buffer_pos_ += result;}// Returns number of bytes used including the current *modrmp.// Writes instruction's right operand to 'tmp_buffer_'.int DisassemblerIA32::PrintRightOperand(byte* modrmp) {  int mod, regop, rm;  get_modrm(*modrmp, &mod, &regop, &rm);  switch (mod) {    case 0:      if (rm == ebp) {        int32_t disp = *reinterpret_cast<int32_t*>(modrmp+1);        AppendToBuffer("[0x%x]", disp);        return 5;      } else if (rm == esp) {        byte sib = *(modrmp + 1);        int scale, index, base;        get_sib(sib, &scale, &index, &base);        if (index == esp && base == esp && scale == 0 /*times_1*/) {          AppendToBuffer("[%s]", NameOfCPURegister(rm));          return 2;        } else if (base == ebp) {          int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2);          AppendToBuffer("[%s*%d+0x%x]",                         NameOfCPURegister(index),                         1 << scale,                         disp);          return 6;        } else if (index != esp && base != ebp) {          // [base+index*scale]          AppendToBuffer("[%s+%s*%d]",                         NameOfCPURegister(base),                         NameOfCPURegister(index),                         1 << scale);          return 2;        } else {          UnimplementedInstruction();          return 1;        }      } else {        AppendToBuffer("[%s]", NameOfCPURegister(rm));        return 1;      }      break;    case 1:  // fall through    case 2:      if (rm == esp) {        byte sib = *(modrmp + 1);        int scale, index, base;        get_sib(sib, &scale, &index, &base);        int disp =            mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 2) : *(modrmp + 2);        if (index == base && index == rm /*esp*/ && scale == 0 /*times_1*/) {          AppendToBuffer("[%s+0x%x]", NameOfCPURegister(rm), disp);        } else {          AppendToBuffer("[%s+%s*%d+0x%x]",                         NameOfCPURegister(base),                         NameOfCPURegister(index),                         1 << scale,                         disp);        }        return mod == 2 ? 6 : 3;      } else {        // No sib.        int disp =            mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 1) : *(modrmp + 1);

⌨️ 快捷键说明

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