Opcode | Encoding | 16-bit | 32-bit | 64-bit | CPUID Feature Flag(s) | Description |
---|---|---|---|---|---|---|
F2 0F 1A /r BNDCU bnd, r/m32 | rm | Valid | Valid | N/E | mpx | Raise a #BR exception if the address in r/m32 is greater than the upper bound of bnd. |
F2 0F 1A /r BNDCU bnd, r/m64 | rm | N/E | N/E | Valid | mpx | Raise a #BR exception if the address in r/m64 is greater than the upper bound of bnd. |
F2 0F 1B /r BNDCN bnd, r/m32 | rm | Valid | Valid | N/E | mpx | Raise a #BR exception if the address in r/m32 is greater than the (inverted) upper bound of bnd. |
F2 0F 1B /r BNDCN bnd, r/m64 | rm | N/E | N/E | Valid | mpx | Raise a #BR exception if the address in r/m64 is greater than the (inverted) upper bound of bnd. |
Encoding
Encoding | Operand 1 | Operand 2 |
---|---|---|
rm | ModRM.reg[r] | ModRM.r/m[r] |
Description
The BNDCU/BNDCN
instructions compare the address in the second source operand against the upper bound in the first source operand. If the second source is greater (outside the bounds), a #BR
exception is raised and BNDSTATUS
is set to 1
.
By default, the value stored in the upper bound is stored in its inverted (one's complement) form. The BNDCU
instruction should be used when that assumption is true, and will invert it before comparison. Otherwise, use the BNDCN
instruction.
If the second source operand is a general purpose register, the value contained in it is treated as the address to compare against. If, however, it is a memory location, the effective address is calculated (see LEA
- Load Effective Address) and used in the comparison. At no time is memory accessed.
Which instruction form is used depends on the operating mode of the processor. In 16-bit and 32-bit modes, the 32-bit form is used. In 64-bit mode, the 64-bit form is used.
Operation
public void BNDCU(Bound bnd, IntPtr addr)
{
// uninvert the stored version (that itself is inverted)
if (addr > ~bnd.Upper)
{
BNDSTATUS.Abd = 0;
BNDSTATUS.EC = 1; // bounds violation
#BR;
}
}
public void BNDCN(Bound bnd, IntPtr addr)
{
if (addr > bnd.Upper)
{
BNDSTATUS.Abd = 0;
BNDSTATUS.EC = 1; // bounds violation
#BR;
}
}
Flags Affected
None.Intrinsics
void _bnd_chk_ptr_ubounds(const void *address)
Exceptions
Real-Address Mode
#BR
- If the bounds test fails.
#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 not100b
). - If a register operand encodes
BND4
throughBND7
.
Virtual-8086 Mode
#BR
- If the bounds test fails.
#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 not100b
). - If a register operand encodes
BND4
throughBND7
.
Protected Mode
#BR
- If the bounds test fails.
#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 not100b
). - If a register operand encodes
BND4
throughBND7
.
Compatibility Mode
#BR
- If the bounds test fails.
#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 not100b
). - If a register operand encodes
BND4
throughBND7
.
Long Mode
#BR
- If the bounds test fails.
#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 not100b
). - If a register operand encodes
BND4
throughBND7
.