?? args-x86.c
字號(hào):
return (1);} /* x86constructArguments() *//*x86operandRegister() Handle a register operand (r8/r16/r32/mm/xmm)Inputs: ptr - opcode pointer opnum - number of current operand (first, second, etc) errstr - where to store errorsReturn: pointer to string containing matching register upon success NULL upon errorSide effects: Upon failure, an error message goes in errstr*/static char *x86operandRegister(struct x86matchInfo *ptr, int opnum, char *errstr){ struct x86OpCode *opPtr; unsigned int operand; int regindex; opPtr = ptr->opPtr; operand = opPtr->operands[opnum]; /* * First check if it is a specific register (R_AL etc). This * occurs in instructions like ADC where a specific register * is encoded into the instruction. */ if ((operand & REGISTER) && (opPtr->opinfo[opnum] != NOOPARG)) { if (opPtr->opinfo[opnum] < 0) { sprintf(errstr, "x86operandRegister: bad operand info\n"); return (0); } if (opPtr->opinfo[opnum] == MODFIELD_RM) return (x86getModRegister(ptr->msinfo.rm, operand)); else return (x86RegistersDASM[opPtr->opinfo[opnum]].name); } if (opPtr->digit == REGRM) { /* * This instruction is defined with a /r as well as a * register operand. The register for this operand * is determined by the REG field of the ModR/M byte. */ assert(ptr->msinfo.modptr != 0); return (x86getModRegister(ptr->msinfo.reg, operand)); } /* if (opPtr->digit == REGRM) */ else if ((opPtr->digit >= 0) && (opPtr->digit <= 7)) { if ((operand & REG_MMX) || (operand & REG_XMM)) { /* * We got a mm or xmm operand */ return (x86getModRegister(ptr->msinfo.rm, operand)); } else { /* * We got an r8/r16/r32 operand. We should never get here: /digit * opcodes always have rm8/rm16/rm32/mm/xmm operands, never r8/r16/r32 * operands. */ sprintf(errstr, "x86operandRegister: error: we got a /digit with a register operand"); return (0); } } else if (opPtr->digit == REGCODE) { /* * This instruction is defined with a +rb/+rw/+rd code * indicating something was added to the last byte of * the opcode which specifies a register. This added * value is stored in ptr->regcode (from x86findOpCode) */ assert(ptr->regcode >= 0); assert(ptr->regcode <= 7); regindex = (-1); if (operand & BITS8) regindex = x86RegisterCodes8[ptr->regcode]; else if (operand & BITS16) regindex = x86RegisterCodes16[ptr->regcode]; else if (operand & BITS32) regindex = x86RegisterCodes32[ptr->regcode]; if (regindex < 0) { sprintf(errstr, "x86operandRegister: invalid register operand for instruction %s (%ld)", x86InstructionNames[opPtr->name], opPtr->operands[opnum]); return (0); } return (x86RegistersDASM[regindex].name); } /* if (opPtr->digit == REGCODE) */ return (0);} /* x86operandRegister() *//*x86operandEffectiveAddress() This routine handles the following operands (which all requireeffective address computations from ModR/M bytes):rm8rm16rm32m8m16m32m64m128xmm?/m*Inputs: ws - disasm workspace ptr - opcode pointer operand - operand flags str - where to store register or addressReturn: -1 upon failure: error message goes in 'str' 1 upon success*/static intx86operandEffectiveAddress(struct disasmWorkspace *ws, struct x86matchInfo *ptr, unsigned int operand, char *str){ char *origstr; char *tmpstr; assert(ptr->msinfo.modptr); origstr = str; if (ptr->msinfo.mod == 3) { /* * Special case: ModR/M bytes C0 -> FF are ambiguous. That is, * their effective addresses can be one of five registers - * we can determine the correct register by looking at the * operand's size attribute. Also, we don't have to worry about * SIB bytes since any ModR/M bytes with a "mod" of 3 have * no SIBs. */ tmpstr = x86getModRegister(ptr->msinfo.rm, operand); if (!tmpstr) { sprintf(origstr, "x86operandEffectiveAddress: x86getModRegister failed"); return (-1); } str += sprintf(str, "%s", tmpstr); return (1); } /* * The r/m operand specifies a memory location, not a register: * we need to calculate the effective address. */ if (operand & BITS8) str += sprintf(str, "byte "); else if (operand & BITS16) str += sprintf(str, "word "); else if (operand & BITS32) str += sprintf(str, "dword "); else if (operand & BITS64) str += sprintf(str, "qword "); else if (operand & BITS80) str += sprintf(str, "tword "); /* FPU */ /* * It is a memory location: use []'s :) */ *str++ = '['; if (ws->prefixFlags & PX_SEGOVER) { assert(ws->segmentOverride != (-1)); str += sprintf(str, "%s:", x86RegistersDASM[ws->segmentOverride].name); } if (ptr->msinfo.modptr->flags & MF_SIB) { /* * Write the base register to str: there is one case * where there is no base register (base = 5, mod = 0) - * see table 2-3 of IAS. */ if (!((ptr->msinfo.base == 5) && (ptr->msinfo.mod == 0))) { tmpstr = x86getSibBaseRegister(ptr->msinfo.base); str += sprintf(str, "%s", tmpstr); if (ptr->msinfo.sibptr->index != M_NONE) *str++ = '+'; } /* * Get the index address */ if (ptr->msinfo.sibptr->index != M_NONE) { tmpstr = x86getModAddrStr(ptr->msinfo.sibptr->index); if (!tmpstr) { sprintf(origstr, "x86operandEffectiveAddress: x86getModAddrStr failed"); return (-1); } str += sprintf(str, "%s", tmpstr); if (ptr->msinfo.scale > 0) str += sprintf(str, "*%d", 1 << ptr->msinfo.scale); } } /* if (ptr->msinfo.modptr->flags & MF_SIB) */ else { tmpstr = x86getModAddrStr(ptr->msinfo.modptr->index); if (!tmpstr) { sprintf(origstr, "x86operandEffectiveAddress: x86getModAddrStr failed"); return (-1); } str += sprintf(str, "%s", tmpstr); } /* * Add any displacements */ if (ptr->msinfo.disp) str += sprintf(str, "+0x%x", ptr->msinfo.disp); *str++ = ']'; *str = '\0'; return (1);} /* x86operandEffectiveAddress() *//*x86operandSegOff() This routine handles the operands ptr16:16 or ptr16:32,which are of the form segment:offset, where segment is the number of bitson the left of the colon, and offset is the number of bits on the right.Inputs: data - opcode data stream operand - flags for this operand str - argument string (or error string)Return: 1 upon success (argument goes in str) 0 upon failure (error goes in str)*/static intx86operandSegOff(unsigned char **data, unsigned int operand, char *str){ int err; unsigned long segment, offset; err = 0; if (operand & OFF16) offset = x86getImmediate(data, BITS16, &err); else if (operand & OFF32) offset = x86getImmediate(data, BITS32, &err); else { sprintf(str, "x86operandSegOff: offset operand is neither 16 nor 32 bits"); return (0); } if (err) { sprintf(str, "x86operandSegOff: x86getImmediate failed"); return (0); } segment = x86getImmediate(data, BITS16, &err); if (err) { sprintf(str, "x86operandSegOff: x86getImmediate failed"); return (0); } sprintf(str, "0x%lx:0x%lx", segment, offset); return (1);} /* x86operandSegOff() *//*x86operandMemoryOffset() This routine is called when we have a moffs8/16/32 operand.The 8/16/32 refer to the size of the data at the offset. The offsetis a 16 or 32 bit value (depending on the size attributes of theinstruction) which follows the opcode.Inputs: ws - disasm workspace data - opcode data stream str - where to store resultReturn: 1 upon success 0 upon failure*/static intx86operandMemoryOffset(struct disasmWorkspace *ws, unsigned char **data, char *str){ unsigned long value; int err; unsigned int sizeattr; err = 0; sizeattr = x86addrSizeAttribute(ws); if (sizeattr & DA_16BITMODE) value = x86getImmediate(data, BITS16, &err); else value = x86getImmediate(data, BITS32, &err); if (err) { sprintf(str, "x86operandMemoryOffset: x86getImmediate failed"); return (0); } if (ws->prefixFlags & PX_SEGOVER) { assert(ws->segmentOverride != (-1)); str += sprintf(str, "%s:", x86RegistersDASM[ws->segmentOverride].name); } sprintf(str, "[+0x%lx]", value); return (1);} /* x86operandMemoryOffset() *//*x86getImmediate() Called when an operand has the IMMEDIATE bit set - obtain theimmediate byte value from 'data'Inputs: data - actual opcode data stream where immediate byte(s) are stored flags - bitmask variable containing size of immediate value err - set to 1 if error occursReturn: value of the immediate byte(s)*/static unsigned longx86getImmediate(unsigned char **data, unsigned int flags, int *err){ unsigned long ret; int length; ret = 0; length = 0; /* * Thank god for little endian :-) */ if (flags & BITS8) { ret = (unsigned char) (*data)[length++]; ++(*data); } else if (flags & BITS16) { ret = (unsigned char) (*data)[length++]; ret += (unsigned char) (*data)[length++] * 256; (*data) += 2; } else if (flags & BITS32) { ret = (unsigned char) (*data)[length++]; ret += (unsigned char) (*data)[length++] * 256; ret += (unsigned char) (*data)[length++] * 65536; ret += (unsigned char) (*data)[length++] * 16777216; (*data) += 4; } else *err = 1; return (ret);} /* x86getImmediate() */
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -