Jump to content

ModR/M

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by 97.102.205.224 (talk) at 23:53, 18 August 2024 (SIB byte: Explain special cases of SIB byte (INDEX may not be RSP; BASE may not be RBP or R13 if no displacement)). 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

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

The other significant addition is the REX prefix.[2]: §1.2.7  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:

  • W: If set, the operation is preformed on 64-bit operands.
  • R: Extends the REG field to 4 bits.
  • X: Extends the index field of the SIB byte (if present) to 4 bits.
  • B: Extends the R/M field (or the SIB byte's base if MOD≠11 R/M=100) to 4 bits.

Note that a missing REX prefix and a prefix of 01000000 are equivalent.

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, whose size is given by the MOD field as usual, which encoded after the SIB byte and added to the final address.[4]

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

The general format is as follows:

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

There are, however, two exceptions:

  • An INDEX of ESP/RSP is forbidden. The encoding INDEX=100 denotes a zero index irrespective of the SCALE field. This does not apply if REX.X=1; R12 (register 1100) may be used as an index. Normally, an addressing mode without an index would simply use a bare ModR/M byte without a SIB byte at all, but this is necessary to encode an ESP/RSP-relative address ([ESP]+disp0/8/32 or [RSP]+disp0/8/32).
  • When MOD=00, a BASE of 101, which would specify ESP/RSP with zero displacement, instead specifies no base register and a 32-bit displacement. This is similar to the treatment of the MOD=00 R/M=101 case. This case also applies when REX.B=1; RBP (register 0101) and R13 (register 1101) may both only be used as a base register with a minimum 8-bit displacement.

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