如何使用内联汇编模仿以下c ++代码?

时间:2013-03-14 07:27:28

标签: c++ mutex inline-assembly

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

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的定义

2 个答案:

答案 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前缀。)