Instruction
BNDLDX
Loads the MPX bounds of a pointer from the bound tables in memory, found by the address the pointer is stored at; MPX has been removed.
- Extensions
- Forms
- 2 (2 Legacy)
- Data
- Intel XED v2026.08.23
Forms
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
on = 0 # CPUID: no MPX: a hint NOP
if cpuid_leaf(7, 0)[1] >> 14 & 1:
cfg = bndcfgu if CPL == 3 else bndcfgs
on = cr4 >> 18 & 1 and cfg & 1 # CR4.OSXSAVE, BNDCFGx.EN
if on and xcr0 >> 3 & 3 == 3: # XCR0's BNDREGS, BNDCSR
if bnd.number > 3: # BND4 to BND15
fault(UD)
la = src.address # where the pointer is
w = 28 # its bits 47 + MAWA to 20
if CPL == 3: # pick the directory's entry
r = cpuid_leaf(7, 0)
w += r[2] >> 17 & 31 # MAWAU; MAWA is 0 below CPL 3
i = la >> 20 & (1 << w) - 1
bde = (cfg >> 12 << 12) + 8 * i
if not canonical(bde):
fault(GP, 0)
bt = load(bde, 64) # the entry: a table's address
if not bt & 1: # not valid: BNDSTATUS gets
bound_fault(bde | 2) # the entry's address, code 2
i = la >> 3 & 0x1FFFF # bits 19:3 pick the table's
bte = (bt >> 3 << 3) + 32 * i # entry, of 32 bytes
if not canonical(bte):
fault(GP, 0)
lb = load(bte, 64)
ub = load(bte + 8, 64)
p = load(bte + 16, 64) # the pointer it was stored for
if p == index_reg(src): # still the pointer's value:
bnd.write(ub << 64 | lb) # its bounds
else:
bnd.write(0) # else bounds that allow all
# nothing is read at src's address; the scale is ignored, and
# RIP-relative addressing is refused (#UD). A fault on the
# table's entry may leave bnd partly written (the SDM)Run on AMD Zen 5 (EPYC 9645): 1 case. It ran where CPUID reported no MPX.
on = 0 # CPUID: no MPX: a hint NOP
if cpuid_leaf(7, 0)[1] >> 14 & 1:
cfg = bndcfgu if CPL == 3 else bndcfgs
on = cr4 >> 18 & 1 and cfg & 1 # CR4.OSXSAVE, BNDCFGx.EN
if on and xcr0 >> 3 & 3 == 3: # XCR0's BNDREGS, BNDCSR
if bnd.number > 3: # BND0 to BND3 only
fault(UD)
la = src.address # where the pointer is
i = la >> 12 & 0xFFFFF # bits 31:12 pick the entry
bde = (low(cfg, 32) >> 12 << 12) + 4 * i
bt = load(bde, 32) # the entry: a table's address
if not bt & 1: # not valid: BNDSTATUS gets
bound_fault(bde | 2) # the entry's address, code 2
i = la >> 2 & 0x3FF # bits 11:2 pick the table's
bte = (bt >> 2 << 2) + 16 * i # entry, of 16 bytes
lb = load(bte, 32)
ub = load(bte + 4, 32)
p = load(bte + 8, 32) # the pointer it was stored for
if p == index_reg(src): # still the pointer's value:
bnd.write(ub << 64 | lb) # its bounds, zero-extended
else:
bnd.write(0) # else bounds that allow all
# the addresses are 32 bits and offsets into DSNot run on a processor: the form does not exist in 64-bit mode, where the probe runs.
Operands
| Operand | Kind | Action |
|---|---|---|
BNDLDX bnd, mib not in 64-bit mode | ||
bnd | explicit | write |
mib | explicit | read |
Flags
None: XED records no flag that the forms test or change.
CPUID and processors
Each form belongs to an XED ISA set. A form can be used when the processor reports every CPUID bit of one of its ISA set's alternatives.
| ISA set | CPUID | Processors |
|---|---|---|
MPX | MPX | Skylake, Comet Lake, Cannon Lake, Skylake-SP, Cascade Lake, Cooper Lake, Goldmont, Goldmont Plus, Tremont, Snow Ridge |
More MPX instructions
Sources
- Intel XED v2026.08.23 (commit
0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model. - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2A, page 3-94 (BNDLDX)
- Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1 (253665-093, September 2026)
The tables are derived from Intel XED, Copyright Intel Corporation, licensed under the Apache License 2.0; x86-64.net converted and reformatted them. The text is our own.