The ModR/M byte is a part of an instruction used when a memory operand is required (used).
It permit to specify:
Below is a picture of an intel instruction format (From appendix b instruction formats and encodings) where you can see the ModR/M field.
Certain encodings of the ModR/M byte require a second addressing byte (the SIB byte).
ModR/M byte has <math> 2^8 = 256</math> possible values by CPU word size (16, 32, … bit): seen under the label Value of ModR/M Byte (in Hexadecimal) in the tables called Addressing form table. There is actually one table by CPU Word Size (ie 16-bit or 32-bit)
Example with the table in 16-bit addressing forms (Section 2.1.5 - Page 509 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual
The figure below demonstrates the interpretation of one ModR/M value. Example for C8.
ModR/M value C8 = 11001000
----------------
Mod = 11
RM = 000
/digit (Opcode) or REG = 001
The Effective Address column lists 32 effective addresses and one of them is assigned to the first operand of an instruction.
See also: Memory Segment - Offset - (Relative|Effective) address.
The selection of an Effective Address is made by using the combination of:
The Mod field, or modifier field combined with rm field gives a total of <math>5</math> bits of information to specify (encode) <math>2^5 = 32</math> possible values:
For example: The row indicated by:
identifies multiple registers in the effective address column:
The register selected is determined by the opcode byte along with the operand-size attribute.
The Reg/Opcode field encodes either:
If the instruction requires a second operand, the seventh row (labeled “REG =”) specifies the use of the 3-bit regopcode field when the field is used to give the location of a second operand that must be a register (general purpose, MMX technology, or XMM)
Rows one through five list the registers. The register selected is determined by:
If the instruction does not require a second operand, then the regopcode field may be used as an opcode extension. This use is represented by the sixth row in the tables (labeled “/digit (Opcode)”). Note that values in row six are represented in decimal form.