atomic64_read在x86中工作,但不适用于x64

时间:2013-11-13 13:53:21

标签: gcc inline-assembly

下面的atomic64_read代码在x86环境中工作,但对x64失败。

    asm volatile(
        "mov %%ebx, %%eax\n"
        "mov %%ecx, %%edx\n"
        "lock cmpxchg8b %1\n"
        : "=&A" (ret)
        : "m" (v->counter64)
        );

有趣的是,锁定操作是指x86中的寄存​​器'ecx'(:edx),但在x64中它指的是'rax'寄存器。

lock cmpxchg8b (%ecx) => 86

lock cmpxchg8b (%rax) => 64

我还尝试转换上面给出的代码,考虑到rax和rcx是64位寄存器。它正确地将值移动到rax寄存器,但在lock语句中给出了段错误。

asm volatile(
    "mov %%rcx, %%rax\n"
    "lock cmpxchg8b %1\n"
    : "=&A" (ret)
    : "m" (v->counter64)
    );

1 个答案:

答案 0 :(得分:1)

原始版本失败,因为“A”约束表示rax / eax / ax / al和/或rdx / edx / dx / dl,而x64 rdx仅为结果分配,因此mov指令会覆盖地址RAX。

你可以将结果分成两半:

uint32_t lo, hi;
asm volatile(
    "mov %%ebx, %%eax\n"
    "mov %%ecx, %%edx\n"
    "lock cmpxchg8b %2\n"
    : "=&a" (lo), "=&d" (hi)
    : "m" (v->counter64)
    );
ret = lo | ((uint64_t)hi << 32);

然而,普通阅读是否足够?

ret = *(volatile uint64_t)&v->counter64

或者内存排序不足?