Opcode | Encoding | 16-bit | 32-bit | 64-bit | Description |
---|---|---|---|---|---|
F0 LOCK | zo | Valid | Valid | Valid | Assert the LOCK# for the duration of the instruction. |
Encoding
Encoding | Operand |
---|---|
zo | None |
Description
The LOCK
prefix asserts the processor's LOCK#
pin for the duration of the prefixed instruction. This has the effect of making any memory accesses in the instruction atomic.
In a multiprocessor environment, the LOCK#
pin ensures that the processor has exclusive access to any shared memory.
Beginning with the Pentium P6, when the LOCK
prefix is used with memory in the core's local cache, the LOCK#
pin may not always be asserted. Instead, only the core's local cache line is locked (resulting in the same effect due to cache coherency).
This prefix may only be used with the following instructions:
ADC
- Add with CarryADD
- AddAND
- Logical ANDBTC
- Bit Test and ComplementBTR
- Bit Test and ResetCMPXCHG
- Compare and ExchangeCMPXCHG8B/CMPXCHG16B
- Compare and Exchange 8/16 BytesDEC
- Decrement by OneINC
- Increment by OneNEG
NOT
OR
SBB
SUB
XADD
XCHG
XOR
Even then, those instructions may only be "locked" with a memory operand. Using the LOCK
prefix with those instructions when using only register operands, or on any other instruction will raise a #UD
exception.
Of historical note, the infamous Pentium "F00F" bug was a bug caused by this prefix. Normally, when encountering the invalid encoding of the CMPXCHG8B
instruction (one using a register operand), the processor would raise a #UD
exception. However, when prefixed with LOCK
, the LOCK#
pin would be asserted when reading the exception handler. As locked reads must be paired with a write, the processor's bus interface would forbid all other memory access until the next write, but the paired write would not arrive. This would ultimately lock up the processor's external bus and prevent any other memory access. The only way to recover from this is to reset the processor.
Operation
public void LOCK()
{
AssertLockThroughThisInstruction();
}
Flags Affected
None.Exceptions
Real-Address Mode
#UD
- If this prefix is used on an instruction without a memory operand for the destination.
- If this prefix is used on an instruction with a memory operand for the destination, but the instruction is not one of:
ADC
,ADD
,AND
,BTC
,BTR
,CMPXCHG
,CMPXCHG8B/CMPXCHG16B
,DEC
,INC
,NEG
,NOT
,OR
,SBB
,SUB
,XOR
,XADD
, orXCHG
.
Virtual-8086 Mode
#UD
- If this prefix is used on an instruction without a memory operand for the destination.
- If this prefix is used on an instruction with a memory operand for the destination, but the instruction is not one of:
ADC
,ADD
,AND
,BTC
,BTR
,CMPXCHG
,CMPXCHG8B/CMPXCHG16B
,DEC
,INC
,NEG
,NOT
,OR
,SBB
,SUB
,XOR
,XADD
, orXCHG
.
Protected Mode
#UD
- If this prefix is used on an instruction without a memory operand for the destination.
- If this prefix is used on an instruction with a memory operand for the destination, but the instruction is not one of:
ADC
,ADD
,AND
,BTC
,BTR
,CMPXCHG
,CMPXCHG8B/CMPXCHG16B
,DEC
,INC
,NEG
,NOT
,OR
,SBB
,SUB
,XOR
,XADD
, orXCHG
.
Compatibility Mode
#UD
- If this prefix is used on an instruction without a memory operand for the destination.
- If this prefix is used on an instruction with a memory operand for the destination, but the instruction is not one of:
ADC
,ADD
,AND
,BTC
,BTR
,CMPXCHG
,CMPXCHG8B/CMPXCHG16B
,DEC
,INC
,NEG
,NOT
,OR
,SBB
,SUB
,XOR
,XADD
, orXCHG
.
Long Mode
#UD
- If this prefix is used on an instruction without a memory operand for the destination.
- If this prefix is used on an instruction with a memory operand for the destination, but the instruction is not one of:
ADC
,ADD
,AND
,BTC
,BTR
,CMPXCHG
,CMPXCHG8B/CMPXCHG16B
,DEC
,INC
,NEG
,NOT
,OR
,SBB
,SUB
,XOR
,XADD
, orXCHG
.