InterlockedCompareExchange用法详解

来源:互联网 发布:吉诺比利04奥运会数据 编辑:程序博客网 时间:2024/06/03 11:16

个人网站:www.asmfocus.com

邮箱:zhangliang1223@qq.com

 

LONG
  InterlockedCompareExchange(
    IN OUT PLONG  Destination,
    IN LONG  Exchange,
    IN LONG  Comparand
    );

InterlockedCompareExchange是把目标操作数(第1参数所指向的内存中的数)与一个值(第3参数)比较,如果相等,则用另一个值(第2参数)与目标操作数(第1参数所指向的内存中的数)交换;InterlockedExchange是不比较直接交换。整个操作过程是锁定内存的,其它处理器不会同时访问内存,从而实现多处理器环境下的线程互斥。

在wrk中找到InterlockedCompareExchange的实现

LONG
FASTCALL
InterlockedCompareExchange(
    IN OUT LONG volatile *Destination,
    IN LONG Exchange,
    IN LONG Comperand
    )
{
    __asm {
        mov     eax, Comperand
        mov     ecx, Destination
        mov     edx, Exchange
   lock cmpxchg [ecx], edx
    }
}

这里解释下cmpxchg汇编指令,CMPXCHG CX,DX
首先进行CMP操作,这个操作就是进行减运算,但不保存结果,只是影响标志位ZF的。
AX CX相减为0,ZF置位为1。
CMPXCHG隐含使用EAX寄存器,根据首操作数的位数确定EAX的位数,就是根据CX来确定
是AX,如果是cl,则就是al,根据CMP结果进行XCHG,相等则第2操作数送到第1操作数,不等则第1操作数送EAX或AX或AL。

象这种隐含使用其他寄存器的指令还有不少。对于哪种操作影响标志位也需要慢慢熟悉。

其实在很久前,CMPXCHG指令是很标准的,它规定第2个操作数必须是EAX/AX/AL,
这样就简单了,先比较2个操作数,如果相等,ZF置1,第2操作数送第1操作数,
如果不等,ZF清0,第1操作数送第2操作数。很标准的“比较交换”。
只不过后来对第2操作数就不做限制必须是EAX/AX/AL了,变成隐含使用,指令功能强大了,但对于刚接触指令的人也带来理解和使用上的困惑。

原创粉丝点击