Jump to content

ModR/M

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by AntiDionysius (talk | contribs) at 22:48, 18 August 2024 (Reverted edit by AntiDionysius (talk) to last version by 97.102.205.224). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

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

Description

Opcodes in x86 are generally one-byte, though two-byte instructions and prefixes exist. ModR/M is the byte following the opcode and specifies two operands for the instruction.[1]: §2.1  One operand is a register, while the other is a register or memory operand. The format is:

Bit 7 6 5 4 3 2 1 0
Usage MOD REG R/M

The REG field specifies the register operand. Instructions which take only one operand do not use this field, and it is instead used as additional opcode bits, allowing eight such 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 

The MOD field specifies the addressing mode for the register/memory operand, and the R/M field specifies the register to use.

If the MOD field is 11, the R/M field specifies a register just like the REG field. (The assigment order is AX, CX, DX, BX, SP, BP, SI, DI.)

For other values of the MOD field, a memory operand is specified, with the a base register specified by the R/M field, to which a displacement is added. If MOD is 00, the displacement is zero. If MOD is 01, an 8-bit signed displacement is used. And is MOD is 10, a word-sized (16 or 32 bits, depending on operating mode) displacement is used.

The interpretation of the R/M field as a base register varies greatly between 16- and 32-bit addressing modes.

In 16-bit mode, the eight possible values of the R/M field specify a base register as follows:

  • 000: [BX + SI] + disp0/8/16
  • 001: [BX + DI] + disp0/8/16
  • 010: [BP + SI] + disp0/8/16
  • 011: [BP + DI] + disp0/8/16
  • 100: [SI] + disp0/8/16
  • 101: [DI] + disp0/8/16
  • 110: [BP] + disp0/8/16
  • 111: [BX] + disp0/8/16

where "disp0/8/16" is the displacement specified by the MOD bits.

As a special exception, the combination MOD=00 R/M=110, which would normally specify [BP] + disp0, instead specifies a 16-bit address (disp16) with no register base at all. To address [BP] + 0, use the 1-byte displacement form with a displacement of 0.

In 32-bit mode, there are many differences. 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:

  • Like in 16-bit mode, the [EBP] + disp0 encoding is usurped for a bare disp32. The [EBP]+0 address must use the [EBP]+disp8 encoding with disp8 set to 0. Note, however, that in 32-bit mode, the encoding for this is MOD=00 R/M=101.
  • The encoding MOD≠11 R/M=100 does not specify [ESP] as a base as one would expect, but instead specifies an § SIB byte is present, and should be used to compute the address.

64-bit changes

The ModR/M byte is central to the changes introduced with AMD's 64-bit extension to the original instruction set. In long mode, any opcode whose highest four bits are 0100 (decimal 4) are considered to be a new prefix, the REX prefix.[2]: §1.2.7  The lowest four bits of the prefix byte serve various purposes, including an extra bit for the REG and R/M fields of the ModR/M byte that follows. Among other changes, expanding these values from three bits to four doubles the number of available processor registers from eight to sixteen.[2]: §1.4 

SIB byte

The SIB byte is an optional post-opcode byte in x86 assembly on the i386 and later, used for complex addressing.

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.[3] The displacement is a constant offset encoded after the SIB byte which is applied to the final address.[4]

A REX prefix can optionally allow the SIB byte to use SSE registers.[1]

Bit 7 6 5 4 3 2 1 0
Usage SCALE INDEX BASE

References

  1. ^ a b c Intel Corporation (2016-09-01). "Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume 2A". Retrieved 2021-09-13.
  2. ^ a b Advanced Micro Devices (2021-03-01). "AMD64 Architecture Programmer's Manual Volume 3: General-Purpose and System Instructions" (PDF). Retrieved 2021-09-13.
  3. ^ Hartman, Chris. "Encoding instructions". University of Alaska Fairbanks. Retrieved 28 July 2022.
  4. ^ "80386 Programmer's Reference Manual -- Section 17.2". www.scs.stanford.edu. Retrieved 28 July 2022.

See also