1

我正在尝试使用原子内联汇编代码模仿以下代码:

struct Node{
    Node * next;
    int value;
}

typedef struct Node * Node_ptr;

Node_ptr store(Node_ptr ** L, Node_ptr * I){
    pthread_mutex_lock (&queue_mutex);
    Node_ptr tmp = **L; 
    **L = *I;
    pthread_mutex_unlock (&queue_mutex)
    return tmp;
}

这是我尝试过的:

Node_ptr tmp;
__asm volatile ("lock; movq %1, %%rax; movq %%rax, %0"
                    : "=r" (tmp)
                    : "r" (**L)
                    : "%rax"
                    );

__asm volatile ("lock; movq %1, %%rax; movq %%rax, %0"
                    : "=r" (**L)
                    : "r" (*I)
                    : "%rax"
                    );
return tmp;

但是,我收到“非法指令”错误,并且无法查看哪里出错了。有人对问题所在有一些见解吗?

谢谢

编辑:添加了 node_ptr 的定义

4

2 回答 2

1

英特尔的手册关于LOCK前缀的主题如下:

LOCK 前缀只能添加到以下指令,并且只能添加到目标操作数是内存操作数的那些指令形式:ADD、ADC、AND、BTC、BTR、BTS、CMPXCHG、CMPXCH8B、DEC、INC、NEG、 NOT、OR、SBB、SUB、XOR、XADD 和 XCHG。如果 LOCK 前缀与这些指令之一一起使用并且源操作数是内存操作数,则可能会生成未定义的操作码异常 (#UD)。如果 LOCK 前缀与任何不在上述列表中的指令一起使用,也会产生未定义的操作码异常。

最好的办法(除了阅读来自英特尔的几千页厚厚的手册)是看看你的编译器为 c++ 代码生成了什么样的输出,这应该会给你一个想法。

于 2013-03-14T08:01:16.230 回答
0

您正在寻找的是CMPXCHG说明。(您仍然需要LOCK前缀。)

于 2013-03-14T08:50:20.973 回答