个人网站:www.asmfocus.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了,变成隐含使用,指令功能强大了,但对于刚接触指令的人也带来理解和使用上的困惑。