?? modsib-x86.c
字號(hào):
/* * libDASM * * Copyright (C) 2000-2003 Patrick Alken * This library comes with absolutely NO WARRANTY * * Should you choose to use and/or modify this source code, please * do so under the terms of the GNU General Public License under which * this library is distributed. * * $Id: modsib-x86.c,v 1.1.1.1 2004/04/26 00:40:18 pa33 Exp $ * * This module contains routines used to process/lookup ModR/M * and SIB byte information. *//* * Some general info on ModR/M and SIB bytes to remind myself * from time to time: * * A ModR/M byte is constructed as follows: * * Bits: 7 6 5 4 3 2 1 0 * Mod Reg/Opcode R/M * * Mod = Combines with the R/M field * * Reg/Opcode = Either a register number or three more bits * of opcode information * * R/M = Either a register or combines with Mod to form * an effective address * * A SIB byte is constructed in the following manner: * * Bits: 7 6 5 4 3 2 1 0 * Scale Index Base * * Scale = A number (0-3) that you must raise 2 to in order to * determine the scaling factor * * Index = A number (0-7) which tells you the effective address * of the SIB byte. I have placed these values in SibTable[]. * * Base = A number (0-7) which tells you the register to use as * the base register. I have placed these registers in * x86SibBaseRegisters[]. */#include <stdio.h>#include <assert.h>#include "common-x86.h"#include "modsib-x86.h"#include "operands-x86.h"/* * Top-level includes */#include "libDASM.h"static struct x86ModAddrInfo *x86getModAddress(struct disasmWorkspace *ws, unsigned char mod, unsigned char reg, unsigned char rm);static unsigned int x86getModSibDisplacement(unsigned char *data, int numBytes);static int x86hasEffectiveOperand(struct x86OpCode *opPtr);/* * This corresponds to table 2-1 in the IAS, Vol 2. The first * index corresponds to the mod field. The second index corresponds * to the r/m field. */static struct x86ModAddrInfo x86ModTable16[MAX_MOD][MAX_RM] = { /* MOD = 0 */ { { M_BX_SI, 0 }, { M_BX_DI, 0 }, { M_BP_SI, 0 }, { M_BP_DI, 0 }, { M_SI, 0 }, { M_DI, 0 }, { M_NONE, MF_DISP16 }, { M_BX, 0 } }, /* MOD = 1 */ { { M_BX_SI, MF_DISP8 }, { M_BX_DI, MF_DISP8 }, { M_BP_SI, MF_DISP8 }, { M_BP_DI, MF_DISP8 }, { M_SI, MF_DISP8 }, { M_DI, MF_DISP8 }, { M_BP, MF_DISP8 }, { M_BX, MF_DISP8 } }, /* MOD = 2 */ { { M_BX_SI, MF_DISP16 }, { M_BX_DI, MF_DISP16 }, { M_BP_SI, MF_DISP16 }, { M_BP_DI, MF_DISP16 }, { M_SI, MF_DISP16 }, { M_DI, MF_DISP16 }, { M_BP, MF_DISP16 }, { M_BX, MF_DISP16 } }, /* * MOD = 3 * * When mod is 3, the r/m field specifies a register rather * than a memory address. The actual register depends on * the bit size of the operand, so we cannot encode it here. * The determination of the actual register will be made later * when we construct the arguments. ie: if we come across * an operand r/m8 with a ModR/M byte with a mod of 3, we will * use an 8 bit register, which will be uniquely determined with * the r/m value. */ { { -1, MF_REGISTER }, { -1, MF_REGISTER }, { -1, MF_REGISTER }, { -1, MF_REGISTER }, { -1, MF_REGISTER }, { -1, MF_REGISTER }, { -1, MF_REGISTER }, { -1, MF_REGISTER } }};/* * This corresponds to table 2-2 in the IAS, Vol 2. The first * index corresponds to the mod field. The second index corresponds * to the r/m field. */static struct x86ModAddrInfo x86ModTable32[MAX_MOD][MAX_RM] = { /* MOD = 0 */ { { M_EAX, 0 }, { M_ECX, 0 }, { M_EDX, 0 }, { M_EBX, 0 }, { M_NONE, MF_SIB }, { M_NONE, MF_DISP32 }, { M_ESI, 0 }, { M_EDI, 0 } }, /* MOD = 1 */ { { M_EAX, MF_DISP8 }, { M_ECX, MF_DISP8 }, { M_EDX, MF_DISP8 }, { M_EBX, MF_DISP8 }, { M_NONE, MF_SIB|MF_DISP8 }, { M_EBP, MF_DISP8 }, { M_ESI, MF_DISP8 }, { M_EDI, MF_DISP8 } }, /* MOD = 2 */ { { M_EAX, MF_DISP32 }, { M_ECX, MF_DISP32 }, { M_EDX, MF_DISP32 }, { M_EBX, MF_DISP32 }, { M_NONE, MF_SIB|MF_DISP32 }, { M_EBP, MF_DISP32 }, { M_ESI, MF_DISP32 }, { M_EDI, MF_DISP32 } }, /* * MOD = 3 * * When mod is 3, the r/m field specifies a register rather * than a memory address. The actual register depends on * the bit size of the operand, so we cannot encode it here. * The determination of the actual register will be made later * when we construct the arguments. ie: if we come across * an operand r/m8 with a ModR/M byte with a mod of 3, we will * use an 8 bit register, which will be uniquely determined with * the r/m value. */ { { -1, MF_REGISTER }, { -1, MF_REGISTER }, { -1, MF_REGISTER }, { -1, MF_REGISTER }, { -1, MF_REGISTER }, { -1, MF_REGISTER }, { -1, MF_REGISTER }, { -1, MF_REGISTER } }};/* * The following x86ModRegisters*[] arrays are used when the ModR/M * byte specifies a register instead of a memory address. This * occurs when we are dealing with r8/r16/r32 operands or with * rm8/rm16/rm32 operands with a MOD of 3 (see above) */static int x86ModRegisters8[] = { M_AL, M_CL, M_DL, M_BL, M_AH, M_CH, M_DH, M_BH};static int x86ModRegisters16[] = { M_AX, M_CX, M_DX, M_BX, M_SP, M_BP, M_SI, M_DI};static int x86ModRegisters32[] = { M_EAX, M_ECX, M_EDX, M_EBX, M_ESP, M_EBP, M_ESI, M_EDI};/* * All possible address offsets for ModR/M bytes: this array * is indexed by the M_xxx values */static char *x86ModAddrOffsets[] = { "ah", "al", "ax", "bh", "bl", "bp", "bx", "bp+di", "bp+si", "bx+di", "bx+si", "ch", "cl", "cx", "dh", "di", "dl", "dx", "eax", "ebp", "ebx", "ecx", "edi", "edx", "esi", "esp", "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "si", "sp", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "" /* M_NONE */};/* * This array corresponds to table 2-3 in the IAS, Vol 2. * We need to store less information than in the ModR/M case * because there are only 8 possible memory offsets. Only * the scale factor changes as we go to higher values of the * SIB byte. */struct x86ModAddrInfo x86SibTable[1][8] = { { { M_EAX, 0 }, { M_ECX, 0 }, { M_EDX, 0 }, { M_EBX, 0 }, { M_NONE, 0 }, { M_EBP, 0 }, { M_ESI, 0 }, { M_EDI, 0 } }};/* * SIB base registers - indexed by 'base' field of SIB byte */static char *x86SibBaseRegisters[] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};/*x86processModSib() Called from x86findOpCode() when a prospective match requires aModR/M (and possibly a SIB) byte. This routine makes sure thebyte in the actual opcode data stream is a valid ModR/M byte forthe given prospective match. If so, it then computes the address(es)and displacements specified by the ModR/M (and SIB) byte(s).Inputs: ws - disasm workspace data - actual opcode data we are trying to disassemble: it should point to the ModR/M byte opPtr - pointer to prospective opcode match
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -