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:
Disasm()