Load Extended Bounds Using Address Translation

Encoding

EncodingOperand 1Operand 2
rmModRM.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;
    }
}
  1. If
  2. CPL
  3. is 3, the user
  4. MAWA
  5. (
  6. MAWAU
  7. ) is used. It's value is enumerated in
  8. CPUID[EAX=7]:ECX[bits 17:23 (MAWAU)]
  9. . Otherwise, the supervisor
  10. MAWA
  11. (
  12. MAWAS
  13. ) 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 LOCK prefix is used.
  • If 16 bit addressing is used, or 32 or 64 bit addressing is used, but without an SIB byte (rm is not 100b).
  • If a register operand encodes BND4 through BND7.
#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 LOCK prefix is used.
  • If 16 bit addressing is used, or 32 or 64 bit addressing is used, but without an SIB byte (rm is not 100b).
  • If a register operand encodes BND4 through BND7.
#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 LOCK prefix is used.
  • If 16 bit addressing is used, or 32 or 64 bit addressing is used, but without an SIB byte (rm is not 100b).
  • If a register operand encodes BND4 through BND7.
#GP(0)
  • If the DS segment contains a NULL segment selector.
  • If the effective address of the Bound Table Entry is outside the DS segment limit.
#PF(fc)
  • If a page fault occurs.

Compatibility Mode

#BR
  • If the Bound Directory Entry is invalid.
#UD
  • If the LOCK prefix is used.
  • If 16 bit addressing is used, or 32 or 64 bit addressing is used, but without an SIB byte (rm is not 100b).
  • If a register operand encodes BND4 through BND7.
#GP(0)
  • If the DS segment contains a NULL segment selector.
  • If the effective address of the Bound Table Entry is outside the DS segment limit.
#PF(fc)
  • If a page fault occurs.

Long Mode

#BR
  • If the Bound Directory Entry is invalid.
#UD
  • If the LOCK prefix is used.
  • If 16 bit addressing is used, or 32 or 64 bit addressing is used, but without an SIB byte (rm is not 100b).
  • If a register operand encodes BND4 through BND7.
#GP(0)
  • If the DS segment contains a NULL segment selector.
  • If the effective address of the Bound Table Entry is outside the DS segment limit.
  • If the memory address (A_BDE or A_BTE) is in non-canonical form.
#PF(fc)
  • If a page fault occurs.