1

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)=> x86

lock cmpxchg8b (%rax)=> x64

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

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

1 回答 1

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

还是内存排序不足?

于 2013-11-13T22:32:40.123 回答