BNDSTX: Store Extended Bounds Using Address Translation

For information about interpreting this page, see the help page.
Opcode and MnemonicEncoding16 bit Mode32 bit Mode64 bit ModeCPUID Feature FlagDescription
NP 0F 1B /r
BNDSTX mib, bnd
RMValidValidValidMPXStore the bounds stored in a bound table entry (BTE) from bnd into mib.

Encoding

EncodingOperand 1Operand 2
RMSIB.base[r] + SIB.index[r]ModRM.reg[w]

Description

The BNDSTX instruction stores the bounds at the source operand to the address pointed to by the destination operand. This is conditional on the value contained in the register referenced in the SIB's index field matching the value stored in the bounds table entry.

The destination operand must be a memory operand encoded using an SIB byte. The base field of the SIB byte contains the address of the bounds table, and the index field contains the buffer's offset. The scale field is ignored (treated as 0b00 (scale of 1)). If a displacement is provided, it is added to the base register's value. At no time is memory referenced by the SIB byte accessed (the memory contained at the address referenced by the base is, however), and the flags are untouched.

Which instruction form (32 or 64 bit) is used depends on the operating mode of the processor. In 16 and 32 bit mode, the 32 bit form is used, and, in 64 bit mode, the 64 bit form is used. If a memory address is used as the second source operand, this distinction is irrelevant.

Operation

This pseudo-code uses C# syntax. A list of the types used is available here.
public void BNDSTX_1632(Sib addr, Bound src)
{
  IntPtr base = addr.base + addr.displacement;
  uint ptr = GPR(addr.index);

  uint a_bde = (base[12..32] << 2) + (BNDCFG[12..32] << 12);
  uint a_bt = mem[a_bde];
  if (a_bt.Bit[0] == 0)
  {
    BNDSTATUS = a_bde | 0x02;
    #BR;
  }

  uint a_bte = (base[2..12] << 4) + (a_bt[2..32] << 2);
  mem[a_bte] = bound.lower;
  mem[a_bte + 4] = bound.upper;
  mem[a_bte + 8] = ptr;
}

public void BNDSTX_64(Bound dest, Sib addr)
{
  IntPtr base = addr.base + addr.displacement;
  uint ptr = GPR(addr.index);

  uint a_bde = (base[20..(48+MAWA)] << 3) + (BNDCFG[12..64] << 12); // see note 1
  uint a_bt = mem[a_bde];
  if (a_bt.Bit[0] == 0)
  {
    BNDSTATUS = a_bde | 0x02;
    #BR;
  }

  ulong a_bte = (base[3..20] << 5) + (a_bt[3..64] << 3);
  mem[a_bte] = bound.lower;
  mem[a_bte + 8] = bound.upper;
  mem[a_bte + 16] = ptr;
}

Notes

  1. If CPL (protection ring) is less than 3, the supervisor MAWA (MAWAS) is used, which is 0. Otherwise, the user MAWA (MAWAU) is used; it's value is enumerated in CPUID.(EAX=07h,ECX=00h):ECX.MAWAU[bits 21..17].

Exceptions

Protected Mode

#BR
If the bound directory entry is invalid.
#UD
If the LOCK prefix is used.
If ModRM.r/m does not encode BND0 through BND3 (i.e. contains a 4, 5, 6, or 7).
If the address size overload prefix (67h) is used when CS.D is 1.
If the address size overload prefix is not used when CS.D is 0.
#GP(0)
If the destination's effective address of the Bound Table entry is outside the DS segment limit.
If the DS segment contains a NULL segment selector.
#PF(fault-code)
If a page fault occurs.

Real-Address Mode

#BR
If the bound directory entry is invalid.
#UD
If the LOCK prefix is used.
If ModRM.r/m does not encode BND0 through BND3 (i.e. contains a 4, 5, 6, or 7).
If 16 bit addressing is used.
#GP(0)
If the destination's effective address of the Bound Table entry is outside the DS segment limit.
If the DS segment contains a NULL segment selector.

Virtual-8086 Mode

#BR
If the bound directory entry is invalid.
#UD
If the LOCK prefix is used.
If ModRM.r/m does not encode BND0 through BND3 (i.e. contains a 4, 5, 6, or 7).
If 16 bit addressing is used.
#GP(0)
If the destination's effective address of the Bound Table entry is outside the DS segment limit.
If the DS segment contains a NULL segment selector.
#PF(fault-code)
If a page fault occurs.

Compatibility Mode

Same exceptions as protected mode.

Long Mode

#BR
If the bound directory entry is invalid.
#UD
If the LOCK prefix is used.
If ModRM.r/m does not encode BND0 through BND3 (i.e. contains any of 4 through 15).
If the address size overload prefix (67h) is used when CS.D is 1.
If the address size overload prefix is not used when CS.D is 0.
#GP(0)
If the memory address (A_BDE or A_BTE) is in non-canonical form.
#PF(fault-code)
If a page fault occurs.

Manual Changes

This is a list of changes that have been made from the Intel® 64 and IA-32 Architectures Software Developer’s Manual. These changes were against version 73 (dated ).

  • The overview table only mentions 32 and 64 bit mode support. However, this instruction is supported in all modes.