如何在gcc内联x86_64 asm中实现128位数字的原子拷贝?
我从学校开始(很久以前)就没有做过汇编,也从来没有做过任何x86,但我在现有的旧代码中发现了一个讨厌的bug,有人没有在应该做的地方做原子运算。编写代码的人早已不在了,这里没有人知道我问题的答案。我需要做的是为128位值创建一个原子副本。我目前拥有的代码如下:如何在gcc内联x86_64 asm中实现128位数字的原子拷贝?,gcc,atomic,inline-assembly,Gcc,Atomic,Inline Assembly,我从学校开始(很久以前)就没有做过汇编,也从来没有做过任何x86,但我在现有的旧代码中发现了一个讨厌的bug,有人没有在应该做的地方做原子运算。编写代码的人早已不在了,这里没有人知道我问题的答案。我需要做的是为128位值创建一个原子副本。我目前拥有的代码如下: void atomic_copy128(volatile void* dest,volatile const void* source) { #if PLATFORM_BITS == 64 #ifdef __INTEL_COMPIL
void atomic_copy128(volatile void* dest,volatile const void* source) {
#if PLATFORM_BITS == 64
#ifdef __INTEL_COMPILER
//For IA64 platform using intel compiler
*((__int64*)source)=__load128((__int64*)dest,((__int64*)source)+1);
#else
//For x86_64 compiled with gcc
__asm__ __volatile__("lock ; movq %0,%1"
: "=r"(*((volatile long *)(source)))
: "r"(*((volatile long *)(dest)))
: "memory");
#endif
#else
#error "128 bit operations not supported on this platform."
#endif
}
这不是我最初尝试的代码,因为我在试图编译和运行它时,对它进行了大量的处理。当我使它成为一条完全无效的指令时,它不会编译。当我运行它时,它会一直执行,直到它碰到这一行,然后生成一条“非法指令”错误消息。我非常感谢您的帮助。据我所知,“movq”最多支持一个内存操作数,而且它的参数大小为64位,因此即使支持两个内存操作数,它也不会提供您正在寻找的原子128位副本。据我所知,“movq”最多支持一个内存操作数,而且它的参数是64位大小的,所以即使支持两个内存操作数,它也不会提供您正在寻找的原子128位副本。对于windows:
::memset( dst, -1, 16 );
_InterlockedCompareExchange128(source, -1, -1, dst );
(但必须删除常量const
)
对于windows的其他用途cmpxchg16b
说明:
::memset( dst, -1, 16 );
_InterlockedCompareExchange128(source, -1, -1, dst );
(但必须删除常量const
)
对于其他用途
cmpxchg16b
说明感谢您的回复!我假设“movdqu”也最多只允许一个内存操作数?如果是这样的话,那么我真的有什么方法可以将它用于原子拷贝操作,因为我不能在一条指令中完成它,对吗?我想的全错了吗?谢谢你的回答!我假设“movdqu”也最多只允许一个内存操作数?如果是这样的话,那么我真的有什么方法可以将它用于原子拷贝操作,因为我不能在一条指令中完成它,对吗?我是不是完全错了?