| Opcode | Encoding | 16-bit | 32-bit | 64-bit | CPUID Feature Flag(s) | Description |
|---|---|---|---|---|---|---|
NP 0F 1A mem/r+sibBNDLDX bnd, mib | rm | Valid | Valid | Valid | mpx | Load the bounds stored in a bound table entry (BTE) from mib into bnd. |
Encoding
| Encoding | Operand 1 | Operand 2 |
|---|---|---|
rm | ModRM.reg[w] | SIB.base + SIB.index |
Description
The BNDLDX instruction conditionally loads the destination operand with the bounds referenced at the address pointed to by the source operand. This is conditional on the value contained in the register referenced in the SIB byte's index field matching the value stored in the bounds table entry. If the check fails, the destination is set to the INIT bounds value (lower = 0, upper = 0), allowing access to all available memory.
The second source 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 containing the buffer' offset. The scale field is ignored. If a displacement is provided, it is added to the base value. At no time is memory directly referenced by the SIB byte accessed (the memory contained at the address referenced by the base is, however), and the flags are untouched.
Operation
public void BNDLDX_1632(Bound dest, Sib addr)
{
IntPtr @base = addr.Base + addr.Displacement;
U32 ptr = GPR(addr.Index);
U32 a_bde = (@base[12..31] << 2) + (BNDCFG[12..31] << 12);
U32 a_bt = Mem32[a_bde];
if (a_bt.Bit[0] == 0)
{
BNDSTATUS.Bde = a_bde;
BNDSTATUS.EC = 2; // invalid BDE
#BR;
}
U32 a_bte = (@base[2..11] << 4) + (a_bt[2..31] << 2);
U32 tmpLower = Mem32[a_bte];
U32 tmpUpper = Mem32[a_bte + 4];
U32 tmpPtr = Mem32[a_bte + 8];
if (tmpPtr == ptr)
{
dest.Lower = tmpLower;
dest.Upper = tmpUpper;
}
else
{
dest.Lower = 0;
dest.Upper = 0;
}
}
public void BNDLDX(Bound dest, Sib addr)
{
IntPtr @base = addr.Base + addr.Displacement;
U64 ptr = GPR(addr.Index);
U64 a_bde = (@base[20..(48+MAWA-1)] << 3) + (BNDCFG[12..63] << 12); // see note 1
U64 a_bt = Mem64[a_bde];
if (a_bt.Bit[0] == 0)
{
BNDSTATUS.Bde = a_bde;
BNDSTATUS.EC = 2; // invalid BDE
#BR;
}
U64 a_bte = (@base[3..19] << 5) + (a_bt[3..63] << 3);
U64 tmpLower = Mem64[a_bte];
U64 tmpUpper = Mem64[a_bte + 8];
U64 tmpPtr = Mem64[a_bte + 16];
if (tmpPtr == ptr)
{
dest.Lower = tmpLower;
dest.Upper = tmpUpper;
}
else
{
dest.Lower = 0;
dest.Upper = 0;
}
}- If
CPL- is 3, the user
MAWA- (
MAWAU- ) is used. It's value is enumerated in
CPUID[EAX=7]:ECX[bits 17:23 (MAWAU)]- . Otherwise, the supervisor
MAWA- (
MAWAS- ) is used, which is 0.
Flags Affected
None.Intrinsics
None. Auto-generated by compiler.
Exceptions
Real-Address Mode
#BR- If the Bound Directory Entry is invalid.
#UD- If the
LOCKprefix is used. - If 16 bit addressing is used, or 32 or 64 bit addressing is used, but without an SIB byte (
rmis not100b). - If a register operand encodes
BND4throughBND7.
#GP(0)- If the effective address of the Bound Table Entry is outside the
DS- segment limit.
Virtual-8086 Mode
#BR- If the Bound Directory Entry is invalid.
#UD- If the
LOCKprefix is used. - If 16 bit addressing is used, or 32 or 64 bit addressing is used, but without an SIB byte (
rmis not100b). - If a register operand encodes
BND4throughBND7.
#GP(0)- If the effective address of the Bound Table Entry is outside the
DS- segment limit.
#PF(fc)- If a page fault occurs.
Protected Mode
#BR- If the Bound Directory Entry is invalid.
#UD- If the
LOCKprefix is used. - If 16 bit addressing is used, or 32 or 64 bit addressing is used, but without an SIB byte (
rmis not100b). - If a register operand encodes
BND4throughBND7.
#GP(0)- If the
DSsegment contains aNULLsegment selector. - If the effective address of the Bound Table Entry is outside the
DSsegment limit.
#PF(fc)- If a page fault occurs.
Compatibility Mode
#BR- If the Bound Directory Entry is invalid.
#UD- If the
LOCKprefix is used. - If 16 bit addressing is used, or 32 or 64 bit addressing is used, but without an SIB byte (
rmis not100b). - If a register operand encodes
BND4throughBND7.
#GP(0)- If the
DSsegment contains aNULLsegment selector. - If the effective address of the Bound Table Entry is outside the
DSsegment limit.
#PF(fc)- If a page fault occurs.
Long Mode
#BR- If the Bound Directory Entry is invalid.
#UD- If the
LOCKprefix is used. - If 16 bit addressing is used, or 32 or 64 bit addressing is used, but without an SIB byte (
rmis not100b). - If a register operand encodes
BND4throughBND7.
#GP(0)- If the
DSsegment contains aNULLsegment selector. - If the effective address of the Bound Table Entry is outside the
DSsegment limit. - If the memory address (
A_BDEorA_BTE) is in non-canonical form.
#PF(fc)- If a page fault occurs.