ModR/M

Last updated

The ModR/M byte is an important part of instruction encoding for the x86 instruction set.

Contents

Description

Opcodes in x86 are generally one-byte, though two-byte instructions and prefixes exist. ModR/M is a byte that, if required, follows the opcode and specifies zero, one, or two operands for the instruction. [1] :§2.1

The format is:

Bit76543210
Usage"Mod""Reg""R/M"

The "reg" field, if specifying an operand, encodes the three least-significant bits of a register index. Which register (general purpose, AVX, etc.) depends on the instruction being executed. Instructions which take only one operand typically do not use this field, but instead repurpose the bits as an "opcode extension", allowing eight instructions to share a single opcode byte. In opcode listings, these are specified by following the opcode with a slash (/) and a digit 0-7. [1] :§3.1.1.1 For example, the opcode for byte increment is FE /0 [1] :3-509 [2] :183, while for byte decrement it is FE /1. [1] :3-321 [2] :171

The "mod" field specifies the addressing mode for the register/memory ("r/m") operand. If the "mod" field is 112, the "r/m" field encodes a register in the same manner as the "reg" field. However, if the "mod" field is anything else (002, 012, or 102), the "r/m" field specifies an addressing mode. The interpretation of these five bits differs between 16- and 32-/64-bit addressing modes.

In 16-bit mode, the eight possible values of the "r/m" field specify a base register as follows: [1] :Table 2-1 [2] :Table A-33 [3] [4]

where "disp" is the displacement specified by the "mod" bits.

As a special exception, the combination mod=002, r/m=1102, which would normally specify [BP + disp0], instead specifies a 16-bit address [disp16] with no register base at all. To address [BP+0], one must use a 1-byte displacement ("disp8") form with a displacement of 0.

This results in the full set of combinations:

x86 Mod & R/M encoding, 16-bit mode [1] :Table 2-1 [2] :Table A-33 [3] [4]
R/MMOD
0001 [lower-alpha 1] 1011
000[BX+SI][BX+SI+disp8][BX+SI+disp16]AL / AX
001[BX+DI][BX+DI+disp8][BX+DI+disp16]CL / CX
010[BP+SI][BP+SI+disp8][BP+SI+disp16]DL / DX
011[BP+DI][BP+DI+disp8][BP+DI+disp16]BL / BX
100[SI][SI+disp8][SI+disp16]AH / SP
101[DI][DI+disp8][DI+disp16]CH / BP
110[disp16][BP+disp8][BP+disp16]DH / SI
111[BX][BX+disp8][BX+disp16]BH / DI

In 32-bit mode, there are many differences. [1] :Table 2-2 [2] :Table A-34 [3] [4] First, the MOD=10 case specifies a 32-bit displacement (disp32). Second, the R/M field specifies only a single base register, using the same encoding as the REG field. There are two exceptions:

x86 Mod & R/M encoding, 32-bit mode [1] :Table 2-2 [2] :Table A-34 [3] [4]
R/MMOD
0001 [lower-alpha 1] 1011
000[EAX][EAX+disp8][EAX+disp32]AL / AX / EAX
001[ECX][ECX+disp8][ECX+disp32]CL / CX / ECX
010[EDX][EDX+disp8][EDX+disp32]DL / DX / EDX
011[EBX][EBX+disp8][EBX+disp32]BL / BX / EBX
100[ SIB]
[ SIB+disp8][ SIB+disp32]AH / SP / ESP
101[disp32][EBP+disp8][EBP+disp32]CH / BP / EBP
110[ESI][ESI+disp8][ESI+disp32]DH / SI / ESI
111[EDI][EDI+disp8][EDI+disp32]BH / DI / EDI

The combination MOD=00 R/M=100, which specifies a SIB byte with no displacement, has a similar special case if the base register is coded as 101 (EBP). In that case, the base register is omitted but a word displacement is used, producing a [SCALE*INDEX+disp32] addressing mode.

SIB byte

The SIB byte is an optional post-opcode byte in x86 assembly on the i386 and later, used for complex addressing. If present, it appears immediately after the ModR/M byte, before any displacements.

SIB bytes are formatted similarly to ModR/M bytes, and take the form of (scale * index) + base + displacement, where the SCALE is 1, 2, 4, or 8. BASE and INDEX each encode a register. [5] The displacement is a constant offset, whose size is given by the MOD field as usual, which encoded after the SIB byte and added to the final address. [3]

A REX prefix allows the SIB byte to use 16 integer registers. [1]

The general format is as follows:

Bit76543210
UsageSCALEINDEXBASE

There are, however, two exceptions:

In 64-bit mode, MOD=00 R/M=101 is reassigned to encode relative addresses [RIP+disp32], so an absolute address [disp32] must be encoded using a SIB byte with both of these exceptions.

Special SIB byte addressing modes

For most instructions that accept a ModR/M byte, encodings with the SIB byte will result in the computation of a single effective address as (scale * index) + base + displacement as described above. However, some newer x86 instruction set extensions have added instructions that use the SIB byte in other, more specialized ways:

For all the instructions that use VSIB, MIB or SIBMEM addressing, the SIB byte is mandatory - instruction encodings without the SIB byte will cause #UD (invalid instruction exception). For VSIB addressing, the INDEX=100 case is not treated specially (it will cause xmm4/ymm4/zmm4 to be used as index register); other than that, the INDEX=100 and the (MOD=00 BASE=101) special-cases work for VSIB/MIB/SIBMEM addressing in the same way as for regular SIB addressing.

64-bit changes

AMD's 64-bit extension to the original instruction set make relatively few changes to 32-bit addressing, with the most significant being that in long mode, 64-bit addressing is the default. 64-bit registers (RAX, RBX, RCX, etc.) are used rather than 32-bit registers for address computation. The displacement is not widened to 64 bits; MOD=11 continues to specify a 32-bit displacement, which is sign-extended to 64 bits. [2] :§1.5

This may be changed with the address size override prefix 0x67, which changes to 32-bit addressing for the following instruction. [2] :§1.2.3

A second major addition is the REX prefix. [2] :§1.2.7,§1.4.4 In long mode, opcodes whose highest four bits are 0100 (decimal 4) are a REX prefix, which provide an additional bit for each register field of the following instruction, doubling the number of available processor registers from eight to sixteen. [2] :§1.4 Specifically, the four low-order bits are:

There is one additional effect of a REX prefix: a REX prefix changes how byte registers are addressed. Without a prefix, the available byte registers are AL/CL/DL/BL, then AH/CH/DH/BH. When a REX prefix is present, even a REX prefix of 01000000, byte instructions consistently address the low byte of the corresponding word registers, so the available byte become AL/CL/DL/BL/SPL/BPL/SIL/DIL. [2] :§2.3.1

The third significant change is RIP-relative addressing. [2] :§1.7  The MOD=00 R/M=101 encoding, which specifies a disp32 address (with no base register) in 32-bit mode, specifies [RIP+disp32] in long mode. With an address-size override prefix, this becomes [EIP+disp32]. [2] :§1.7.3 The absolute [disp32] mode may be obtained by using MOD=00 R/M=100 to force use of a SIB byte, followed by a SIB byte with BASE=101 and INDEX=100. [2] :§1.7.1

For the special-case addressing encodings R/M=100 (to force a SIB byte), MOD=00 R/M=101 (substitute RIP+disp32), and MOD=00 R/M=100 BASE=101 (substitute disp32), the REX.B prefix is not considered. [2] :§1.8.2 These special-case encodings apply to registers R12 (binary 1100) and R13 (binary 1101) as well, [4] and the same slightly-longer encodings must be used. This is because these exceptions change the encoded instruction size, so must be decoded very quickly so that the following instruction may be located.

The special case where INDEX=100 suppresses the index register (scaling RSP is forbidden), however, does respect the REX.X bit; it is possible to scale R12. [2] :§1.8.2 This is for two reasons:

  1. there is no alternative way to encode indexing with R12, so this would be a serious limitation, and
  2. the exception changes the computed address but not the encoded instruction size, so there is more time in the instruction pipeline to resolve the special case.

See also

Notes

  1. 1 2 When the MOD=01 encoding is used in the ModR/M byte of an AVX-512 or AVX10 instruction encoded with an EVEX prefix, the displacement encoded in the instruction's disp8 byte will be scaled. The scaling factor used will usually be given by the memory operand size (although some exceptions exist, e.g. the VGATHER*, VSCATTER*, VCOMPRESS*, VEXPAND* instructions, which use the single-element size as scaling factor).

    For example, the instruction encoding 62 f1 7d 48 6f 47 01 (with the EVEX prefix in italics and ModR/M byte in bold) in 64-bit mode encodes the instruction vmovdqa32 zmm0,[rdi+0x40], which loads a 64-byte vector from memory and therefore gets its disp8 byte 01 multiplied with 64. This scaling is only applied to 8-bit displacements — 16-bit and 32-bit displacements are not scaled. [1] :§2.7.5

  2. On some early x86 processors, such as e.g. Intel 386 and 486 [6] and all Cyrix processors, [7] a SIB-byte encoded with INDEX=100 and the SCALE field set to a nonzero value would result in an undefined effective-address. On newer processors, from the P5 Pentium onwards, this combination is no longer undefined.
  3. Some assemblers/disassemblers (such as e.g. gas/objdump from GNU Binutils version 2.19 or later) support the use of the eiz/riz pseudo-register to indicate an address encoding that uses a SIB-byte with INDEX=100. (eiz is used for 32-bit addressing, riz for 64-bit.)

    For example, in 32-bit mode, the instruction encoding 8D 74 26 00 may disassemble to - or be assembled from - lea esi,[esi+eiz*1+0x0]. [8] [9]

Related Research Articles

x86 Family of instruction set architectures

x86 is a family of complex instruction set computer (CISC) instruction set architectures initially developed by Intel based on the 8086 microprocessor and its 8-bit-external-bus variant, the 8088. The 8086 was introduced in 1978 as a fully 16-bit extension of 8-bit Intel's 8080 microprocessor, with memory segmentation as a solution for addressing more memory than can be covered by a plain 16-bit address. The term "x86" came into being because the names of several successors to Intel's 8086 processor end in "86", including the 80186, 80286, 80386 and 80486. Colloquially, their names were "186", "286", "386" and "486".

In computer science, an instruction set architecture (ISA) is an abstract model that generally defines how software controls the CPU in a computer or a family of computers. A device or program that executes instructions described by that ISA, such as a central processing unit (CPU), is called an implementation of that ISA.

x86 assembly language is the name for the family of assembly languages which provide some level of backward compatibility with CPUs back to the Intel 8008 microprocessor, which was launched in April 1972. It is used to produce object code for the x86 class of processors.

<span class="mw-page-title-main">Index register</span> CPU register used for modifying operand addresses

An index register in a computer's CPU is a processor register used for pointing to operand addresses during the run of a program. It is useful for stepping through strings and arrays. It can also be used for holding loop iterations and counters. In some architectures it is used for read/writing blocks of memory. Depending on the architecture it may be a dedicated index register or a general-purpose register. Some instruction sets allow more than one index register to be used; in that case additional instruction fields may specify which index registers to use.

The x86 instruction set refers to the set of instructions that x86-compatible microprocessors support. The instructions are usually part of an executable program, often stored as a computer file and executed on the processor.

Addressing modes are an aspect of the instruction set architecture in most central processing unit (CPU) designs. The various addressing modes that are defined in a given instruction set architecture define how the machine language instructions in that architecture identify the operand(s) of each instruction. An addressing mode specifies how to calculate the effective memory address of an operand by using information held in registers and/or constants contained within a machine instruction or elsewhere.

In computer engineering, an orthogonal instruction set is an instruction set architecture where all instruction types can use all addressing modes. It is "orthogonal" in the sense that the instruction type and the addressing mode vary independently. An orthogonal instruction set does not impose a limitation that requires a certain instruction to use a specific register so there is little overlapping of instruction functionality.

<span class="mw-page-title-main">Clipper architecture</span> 32-bit RISC-like computing architecture

The Clipper architecture is a 32-bit RISC-like instruction set architecture designed by Fairchild Semiconductor. The architecture never enjoyed much market success, and the only computer manufacturers to create major product lines using Clipper processors were Intergraph and High Level Hardware, although Opus Systems offered a product based on the Clipper as part of its Personal Mainframe range. The first processors using the Clipper architecture were designed and sold by Fairchild, but the division responsible for them was subsequently sold to Intergraph in 1987; Intergraph continued work on Clipper processors for use in its own systems.

z/Architecture, initially and briefly called ESA Modal Extensions (ESAME), is IBM's 64-bit complex instruction set computer (CISC) instruction set architecture, implemented by its mainframe computers. IBM introduced its first z/Architecture-based system, the z900, in late 2000. Later z/Architecture systems include the IBM z800, z990, z890, System z9, System z10, zEnterprise 196, zEnterprise 114, zEC12, zBC12, z13, z14, z15 and z16.

<span class="mw-page-title-main">TI-990</span> Series of 16-bit computers by Texas Instruments.

The TI-990 was a series of 16-bit minicomputers sold by Texas Instruments (TI) in the 1970s and 1980s. The TI-990 was a replacement for TI's earlier minicomputer systems, the TI-960 and the TI-980. It had several unique features, and was easier to program than its predecessors.

TLCS is a prefix applied to microcontrollers made by Toshiba. The product line includes multiple families of CISC and RISC architectures. Individual components generally have a part number beginning with "TMP". E.g. the TMP8048AP is a member of the TLCS-48 family.

The PDP-11 architecture is a 16-bit CISC instruction set architecture (ISA) developed by Digital Equipment Corporation (DEC). It is implemented by central processing units (CPUs) and microprocessors used in PDP-11 minicomputers. It was in wide use during the 1970s, but was eventually overshadowed by the more powerful VAX architecture in the 1980s.

An instruction set architecture (ISA) is an abstract model of a computer, also referred to as computer architecture. A realization of an ISA is called an implementation. An ISA permits multiple implementations that may vary in performance, physical size, and monetary cost ; because the ISA serves as the interface between software and hardware. Software that has been written for an ISA can run on different implementations of the same ISA. This has enabled binary compatibility between different generations of computers to be easily achieved, and the development of computer families. Both of these developments have helped to lower the cost of computers and to increase their applicability. For these reasons, the ISA is one of the most important abstractions in computing today.

The XOP instruction set, announced by AMD on May 1, 2009, is an extension to the 128-bit SSE core instructions in the x86 and AMD64 instruction set for the Bulldozer processor core, which was released on October 12, 2011. However AMD removed support for XOP from Zen (microarchitecture) onward.

The VEX prefix and VEX coding scheme are an extension to the IA-32 and x86-64 instruction set architecture for microprocessors from Intel, AMD and others.

The EVEX prefix and corresponding coding scheme is an extension to the 32-bit x86 (IA-32) and 64-bit x86-64 (AMD64) instruction set architecture. EVEX is based on, but should not be confused with the MVEX prefix used by the Knights Corner processor.

The PIC instruction set refers to the set of instructions that Microchip Technology PIC or dsPIC microcontroller supports. The instructions are usually programmed into the Flash memory of the processor, and automatically executed by the microcontroller on startup.

<span class="mw-page-title-main">STM8</span>

The STM8 is an 8-bit microcontroller family by STMicroelectronics. The STM8 microcontrollers use an extended variant of the ST7 microcontroller architecture. STM8 microcontrollers are particularly low cost for a full-featured 8-bit microcontroller.

The x86 instruction set has several times been extended with SIMD instruction set extensions. These extensions, starting from the MMX instruction set extension introduced with Pentium MMX in 1997, typically define sets of wide registers and instructions that subdivide these registers into fixed-size lanes and perform a computation for each lane in parallel.

References

  1. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Intel Corporation (June 2024). "Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume 2: Instruction Set Reference, A-Z" (PDF). 325383-084US. Archived (PDF) from the original on Aug 19, 2024. Retrieved 2024-09-10.
  2. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Advanced Micro Devices (March 2024). "AMD64 Architecture Programmer's Manual Volume 3: General-Purpose and System Instructions" (PDF). rev. 3.36. Retrieved 2024-08-19.
  3. 1 2 3 4 5 "80386 Programmer's Reference Manual -- Section 17.2". www.scs.stanford.edu. Retrieved 28 July 2022.
  4. 1 2 3 4 5 "X86-64 Instruction Encoding". OSDev.org. Retrieved 2024-08-19.
  5. Hartman, Chris. "Encoding instructions". University of Alaska Fairbanks. Retrieved 28 July 2022.
  6. Intel, i486 Microprocessor, order no. 240440-002, Nov 1989, page 155
  7. Cyrix, Cyrix M II Data Book, order no. 94329, 26 Feb 1999, section 6.2.6, page 217
  8. H.J. Lu, Re: objdump: unknown register %eiz, 6 Jan 2009. Binutils mailing list
  9. Stack Overflow, What is register %eiz?, 31 Mar 2010.