3

OS に依存しないロックレス キューを作成しています。キューは正常に動作します (デフォルトの 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

4

2 に答える 2

14

C11以降では、最近<stdatomic.h>広くサポートされているを使用する必要があります。

#include <stdatomic.h>

atomic_compare_exchangeを参照してください。ここでは、正確なセマンティクスを要約しようとはしません。

C11がなければ、両方のプラットフォームの組み込み関数でそれを行うことができ、アセンブリは必要ありません。

#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のドキュメントGCCのドキュメントを参照してください。__GNUC__Clangは事前定義されたマクロとの互換性をアドバタイズするため、これは変更なしでClangでも機能するはずです。

于 2012-11-07T11:04:31.953 に答える
5

http://web.itu.edu.tr/kesgin/mul06/intel/instr/cmpxchg.htmlによるとcmpxchg、3 つのパラメーターではなく 2 つのパラメーターを取ります。

おそらく、http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=arch/x86/include/asm/cmpxchg.hも興味深いものです。

于 2012-11-07T10:41:42.080 に答える