在汇编程序OS独立的原子比较和交换

时间:2012-11-07 10:32:56

标签: c linux windows assembly atomic

我正在编写独立于操作系统的无锁队列,队列工作正常(使用默认的windows \ linux原子CAS),但我想让队列工作而不需要在linux和windows中进行任何更改。所以我猜我应该在汇编程序中编写自己的CAS,还是有其他方法可以实现?

到目前为止,我有这段代码:

global _CAS

_CAS:

    mov eax, [esp+4]    
    mov edx, [esp+8]    
    mov ecx, [esp+12]   

    ;XCHG eax, edx  <- this function works fine
     CMPXCHG  ecx, eax, ebx 

    ret

我知道我仍然必须在lock之前添加CMPXCHG并且它应该与结构一起使用,但是现在我对使其工作更感兴趣。

我使用nasm-2.10.05使用此命令编译nasm.exe -f elf -o cas.o cas.asm 我收到此错误testas\cas.asm:14: error: invalid combination of opcode and operands

2 个答案:

答案 0 :(得分:12)

你可以在两个平台上使用内在函数来完成它,不需要汇编:

#ifdef _MSC_VER
# include <intrin.h>
# define CAS(ptr, oldval, newval) \
    _InterlockedCompareExchange(ptr, newval, oldval)
#elif __GNUC__
# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
#  error "requires GCC 4.1 or greater"
# endif
# define CAS(ptr, oldval, newval) \
    __sync_val_compare_and_swap(ptr, oldval, newval)
#else
# error "CAS not supported on this platform"
#endif

这两个都支持以下界面:

/* If the current value of *ptr is oldval, then write newval
   into *ptr.  Returns the initial value of *ptr.  */
long CAS(long *ptr, long oldval, long newval);

请参阅MSDN documentationGCC documentation。这也应该对Clang起作用而不做任何修改,因为Clang宣传__GNUC__与其预定义宏的兼容性。

答案 1 :(得分:3)