我正在尝试使用原子内联汇编代码模仿以下代码:
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的定义
答案 0 :(得分: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 ++代码生成什么样的输出,这应该给你一个想法。
答案 1 :(得分:0)
您正在寻找的是CMPXCHG
指令。 (您仍然需要LOCK
前缀。)