如何在 gcc 内联 x86_64 asm 中进行 128 位数字的原子复制?

发布于 2024-10-08 04:23:47 字数 830 浏览 6 评论 0原文

我自从上学以来(很久以前)就没有做过汇编,也从来没有做过任何x86,但我在旧的现有代码中发现了一个令人讨厌的错误,其中有人没有在他们应该做的地方执行原子操作。编写代码的人早已去世,这里没有人知道我的问题的答案。我需要做的是为 128 位值创建一个原子副本。我当前拥有的代码如下:

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
}

这不是我最初尝试的代码,因为我在尝试编译和运行它时已经对其进行了相当多的修改。当我将其设置为完全无效的指令时,它无法编译。当我运行它时,它会执行直到到达此行,然后生成“非法指令”错误消息。我将不胜感激任何帮助。

I haven't done assembly since school (eons ago) and have never done any x86, but I have found a pesky bug in old existing code where somebody isn't doing an atomic op where they should be. The person who wrote the code is long gone and nobody around here knows the answer to my question. What I need to do is create an atomic copy for 128-bit values. The code I currently have is as follows:

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
}

This isn't the code that I originally tried, since I've messed with it quite a bit while trying get it to compile and run. When I make it a totally invalid instruction, it does not compile. When I run this, it executes until it hits this line and then generates a "Illegal instruction" error message. I'd appreciate any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝颜夕 2024-10-15 04:23:47

据我所知,“movq”最多支持一个内存操作数,而且它的参数无论如何都是64位大小,所以即使支持两个内存操作数,它仍然不会给你原子的128位副本正在寻找。

As far as I know, "movq" supports at most one memory operand, and its arguments are of 64-bit size anyway, so even if two memory operands were supported, it still wouldn't give you that atomic 128-bit copy you're looking for.

半枫 2024-10-15 04:23:47

对于 Windows:(

::memset( dst, -1, 16 );
_InterlockedCompareExchange128(source, -1, -1, dst );

但必须删除 const

对于其他用途 cmpxchg16b 指令

For windows:

::memset( dst, -1, 16 );
_InterlockedCompareExchange128(source, -1, -1, dst );

(but const must be deleted)

For other use cmpxchg16b instruction

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文