今天在阅读鹏大的一片博文,关于opcode的资料,看到了貌似书上没有讲过也从未见过的指令,再此记录一下。
LOCK总线封锁信号,三态输出,低电平有效。LOCK有效时表示CPU不允许其它总线主控者占用总线。这个信号由软件设置,当前指令前加上LOCK前缀时,则在执行这条指令期间LOCK保持有效,阻止其它主控者使用总线。说白了就是lock前缀只保证对当前指令要访问的内存互斥。
也是说lock后,就是一个原子操作。原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程),在单处理器系统(UniProcessor,简称 UP)中,能够在单条指令中完成的操作都可以认为是原子操作,因为中断只能发生在指令与指令之间。在多处理器系统(Symmetric Multi-Processor,简称 SMP)中情况有所不同,由于系统中有多个处理器在独立的运行,即使在能单条指令中完成的操作也可能受到干扰。
在所有的 X86 CPU 上都具有锁定一个特定内存地址的能力,当这个特定内存地址被锁定后,它就可以阻止其他的系统总线读取或修改这个内存地址。这种能力是通过 LOCK 指令前缀再加上下面的汇编指令来实现的。当使用 LOCK 指令前缀时,它会使 CPU 宣告一个 LOCK# 信号,这样就能确保在多处理器系统或多线程竞争的环境下互斥地使用这个内存地址。当指令执行完毕,这个锁定动作也就会消失。
能够和 LOCK 指令前缀一起使用的指令如下所示:
BT, BTS, BTR, BTC (mem, reg/imm)
XCHG, XADD (reg, mem / mem, reg)
ADD, OR, ADC, SBB (mem, reg/imm)
AND, SUB, XOR (mem, reg/imm)
NOT, NEG, INC, DEC (mem)
注意:XCHG 和 XADD (以及所有以 ‘X’ 开头的指令)都能够保证在多处理器系统下的原子操作,它们总会宣告一个 “LOCK#” 信号,而不管有没有 LOCK 前缀。
Intel的手册上对其的解释是:
Causes the processor’s LOCK# signal to be asserted during execution of the accompanying instruction (turns the instruction into an atomic instruction). In a multiprocessor environment, the LOCK#
signal insures that the processor has exclusive use of any shared memory while the signal is asserted.
也就是说lock会使紧跟在其后面的指令变成 atomic instruction。暂时的锁一下总线,指令执行完了,总线就解锁了!!!
当执行: lock nop
会有异常产生。
An undefined opcodeexception will be generated if the LOCK prefix is used with any other instruction except ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG,DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG.
LOCK可以用来实现原子操作,就不多说了,上边已经说得很清楚了.
其他几个常用前缀:
—F0H—LOCK prefix.
—F2H—REPNE/REPNZ prefix (used only with string instructions)
—F3H—REP prefix (used only with string instructions).
—F3H—REPE/REPZ prefix (used only with string instructions).
—F3H—Streaming SIMD Extensions prefix.