t_operand
Describes operand or pseudooperand of the 80x86 command.
typedef
struct t_operand
{
// Description of disassembled operand
// Description of operand.
ulong
features;
// Operand features, set of OP_xxx
ulong
arg;
// Operand type, set of B_xxx
int
optype;
// DEC_INT, DEC_FLOAT or DEC_UNKNOWN
int
opsize;
// Total size of data, bytes
int
granularity; //
Size of element (opsize exc. MMX/SSE)
int
reg;
// REG_xxx (also ESP in POP) or REG_UNDEF
ulong
uses;
// List of used regs (not in address!)
ulong
modifies;
// List of modified regs (not in addr!)
// Description of memory address.
int
seg;
// Selector (SEG_xxx)
uchar
scale[NREG]; //
Scales of registers in memory address
ulong
aregs;
// List of registers used in address
ulong
opconst;
// Constant or const part of address
// Value of operand.
ulong
offset;
// Offset to selector (usually addr)
ulong
selector;
// Immediate selector in far jump/call
ulong
addr;
// Address of operand in memory
union {
ulong
u;
// Value of operand (integer form)
signed
long
s;
// Value of operand (signed form)
uchar value[16];
}; // Value of operand
(general form)
uchar
actual[16];
// Actual memory (if OP_ACTVALID)
// Textual decoding.
wchar_t
text[TEXTLEN]; // Operand,
decoded to text
wchar_t
comment[TEXTLEN]; // Commented address and
contents
} t_operand;
Members:
features
Features of the operand as a combination of zero or more of the following flags. If features is 0, operand is unavailable:Location of the operand, only one is allowed:
OP_REGISTER - operand is a general-purpose register reg (EAX, CX, BH etc.)
OP_SEGREG - operand is a segment register reg (ES, CS, SS, DS, FS or GS)
OP_FPUREG - operand is a FPU register reg (ST0 .. ST7)
OP_MMXREG - operand is a MMX register reg (MM0 .. MM7)
OP_3DNOWREG - operand is a 3DNow! register reg (MM0 .. MM7)
OP_SSEREG - operand is a SSE register reg (XMM0 .. XMM7)
OP_CREG - operand is a control register reg (CR0 .. CR7)
OP_DREG - operand is a debug register reg (DR0 .. DR7)
OP_MEMORY - operand is in memory (seg, scale/aregs, opconst)
OP_CONST - operand is an immediate opconst
OP_PORT - operand is an I/O port
Additional operand properties:
OP_INVALID - invalid operand, like register where only memory is allowed
OP_PSEUDO - pseudooperand (missing in mnenonics, like ESP in PUSH EAX or EAX and EDX in CDQ)
OP_MOD - command may change or update operand
OP_MODREG - operand describes memory but as a side effect changes reg (like ESP by POP EAX or ESI/EDI by MOVSB)
OP_REL - operand is either offset to the IP (like in relative jumps) or includes fixuped opconst
OP_IMPORT - value of the operand is imported from different module
OP_SELECTOR - operand includes immediate selector (JMP FAR xxxx:yyyyyyyy)
Additional properties of memory address:
OP_INDEXED - memory address contains registers (scale/aregs)
OP_OPCONST - memory address contains opconst
OP_ADDR16 - 16-bit memory address
OP_ADDR32 - explicit 32-bit memory address (not used by Disasm())
Value of the operand:
OP_OFFSOK - offset to selector is valid. If seg is ES, CS, SS or DS and its contents is not available, OllyDbg assumes zero base
OP_ADDROK - addr is valid
OP_VALUEOK - value of the operand (u, s or value, max. 16 bytes) is valid
OP_PREDADDR - addr is predicted, not real
OP_PREDVAL - value of the operand is predicted, not real
OP_RTLOGMEM - memory contents is restored from the run trace
OP_ACTVALID - contents of actual is valid
Pseudooperands, used only in assembler search models:
OP_ANYMEM - accept any memory location
OP_ANY - accept any operand
arg
Type of the operand as a combination of flags B_xxx
optype
One of the following constants that determine type of the data in the operand:
DEC_INT - value of the operand must be interpreted as an integer number
DEC_FLOAT - value of the operand must be interpreted as a floating-point number
DEC_UNKNOWN - type of data is not known
opsize
Total size of the operand, bytes
granularity
If operand consists of several separate pieces (MMX, 3DNow! or SSE), size of each piece in bytes. Otherwise, either 0 or opsize
reg
If operand specifies a register (like EAX, ST0 or DR7), index of this register. If operand is OP_MEMORY but as a side effect modifies general purpose register (OP_MODREG), index of this register. Otherwise, REG_UNDEF.
For example, MOVSD has two memory (pseudo)operands: [ESI] and [ES:EDI].
First operand modifies ESI and second - EDI. POP EAX has two
operands: EAX and [ESP]. Second operand modifies ESP.
uses
List
of 32-bit general purpose registers used by the operand. Does not
include registers that form memory address. EAX is bit 0x01, EDX - bit
0x02 etc. Usually it is empty or contains single register. PUSHA
uses all registers.
Note that byte register AH has index 1 but is part of the 32-bit register EAX with index 0. In this case uses will specify EAX.
Note
also the subtle difference between used and modified registers.
Register is used if it participates in the calculations of result.
Register is modified if its contents may change as a result of the
command execution. In the command MOV EAX,EBX register EAX is modified
but not used, and register EBX is used but not modified. In the command
ADD EAX,EBX both registers are used but only EAX is modified
modifies
List of
32-bit general purpose registers used by the operand. Does not include
registers that form memory address. EAX is bit 0x01, EDX - bit 0x02
etc. Usually it is empty or contains single register. POPA modifies all
registers. Se also discussion in the previous member
seg
Index of the segment register explicitly or implicitly specified in the memory address, or SEG_UNDEF if there is no associated segment register. Note that OP_SEGREGs are specified in reg and set seg to SEG_UNDEF
scale
Scale
factors of general purpose registers that form memory address. If
operand is EAX, all scales are 0 because this is not a memory address.
If operand is [123456], all scales are also 0 because address does not
include any registers. For [EAX+4*EDI+123456], scale[REG_EAX] is set to 1, scale[REG_EDI] is 4 and all other scales are 0
aregs
List of 32-bit general purpose registers that form memory address. For example, if address is [EAX+4*EDI+123456], aregs is (1<<REG_EAX) | (1<<REG_EDI)
opconst
If operand is of type OP_CONST, contains immediate constant. If operand is OP_MEMORY,
immediate part of address. Note that in the command PUSH EAX register
ESP is predecremented and data will be saved to the
pseudooperand [ESP-4]. In this cas opconst is set to -4
offset
Offset part of the full memory address, or 0 if address cannot be calculated or operand is not in the memory
selector
Value of immediate selector in the immedate far jumps and calls. For example, if command is JMP FFFF:00000000, selector will contain FFFF
addr
Final memory address,
or 0 if address cannot be calculated or operand is not in the memory.
If command specifies no segment, usually it is the same as offset.
In the flat Win32 model, CS, SS, DS and ES have zero base. Segment
register FS points to the Thread Information Block, therefore to
calculate address OllyDbg must know the contents of the FS and read
corresponding selector
u, s, value
Value of the operand, defined only if OP_VALUEOK is set
actual
For internal use
text
Operand decoded to text, or empty string if decoding to text is not requested
comment
Operand-specific comment, or empty string if commenting is not requested or Disasm has nothing to say about this operand
See
also: