Windows Interlocked系列函数

2019-08-13 10:56:26 浏览数 (1)

本文以InterlockedIncrement为例,来说明Windows Interlocked系列函数的实现原理。 一、InterlockedIncrement反汇编代码

如下C 代码:

#include <windows.h>

int main() { LONG l = 1; LONG j = InterlockedIncrement(&l); return 0; }

对应的反汇编代码如下:

LONG l = 1; 002D08A8 mov dword ptr [l],1 LONG j = InterlockedIncrement(&l); 002D08AF mov eax,1 002D08B4 lock xadd dword ptr [l],eax 002D08B9 inc eax 002D08BA mov dword ptr [j],eax

这里写图片描述

从上面代码可以看出,InterlockedIncrement主要是通过lock和xadd这2个汇编指令来实现的。 二、lock与xadd指令 2.1 lock

lock前缀用于锁定指定的内存地址,当这个特定内存地址被锁定后,它就可以阻止其他的系统总线读取或修改这个内存地址,从而实现原子操作。 可以结合lock使用的汇编指令如下:

BT, BTS, BTR, BTC XCHG, XADD ADD, OR, ADC, SBB AND, SUB, XOR NOT, NEG, INC, DEC

2.2 xadd

xadd指令完成交换并相加的功能。如XADD r/m32, r32,即交换r32 与r/m32;并将相加的和存储到 r/m32中。

关于xadd指令可以参考: http://scc.qibebt.cas.cn/docs/optimization/VTune(TM) User’s Guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/instruct32_hh/vc325.htm

三、InterlockedIncrement过程分析

InterlockedIncrement的处理过程如下: 【1】将eax赋值为1,即mov eax, 1 【2】使用一个xadd命令完成了下面的操作,通过伪代码表示如下:

// [l]和eax交换 temp = [l] [l] = eax eax = temp

// 将相加的和保存到[l]参数中 [l] = eax [l]

从上面伪代码可以看到,一个xadd指令完成了多步操作,且是针对内存地址的操作,所以这行指令使用了lock前缀修饰。

【3】因为InterlockedIncrement函数返回值也会返回自增的结果,且因win32汇编的函数返回值保存在eax中,所以此时eax还要自增1(即inc eax)。

0 人点赞