内联汇编我该怎么办“非法指令(核心转储)”

时间:2012-09-16 21:31:09

标签: inline inline-assembly

下面的内联汇编代码有什么问题吗? 运行spinlock_lock函数时遇到“非法指令(核心转储)”。

void spinlock_lock(struct spinlock * lock) {

    int a;
    __asm__ __volatile__("movl %0, %%eax;"
                         "test %%eax, %%eax;"
                         "jnz spinlock_lock;"
                         :"=r"(a)
                         :"r"(lock->cmos_lock)
                         :"eax");

    __asm__ __volatile__ ("lock; cmpxchg %%edx, %0\n"
                          :"=r"(a)
                          :"r"(lock->cmos_lock)
                          :"edx", "memory");

1 个答案:

答案 0 :(得分:2)

问题是你的分支;通常(x86)the called function will save the frame pointer on the stack before executing any other code

您的jnz spinlock_lock分支将分支回整个函数的入口点,从而在返回内联汇编程序之前再次保存帧指针。保存帧指针足够多次,你将耗尽堆栈。更不用说如果你通过在其外部分支离开你的内联汇编程序,你的寄存器可能不再包含你认为他们所做的。

您可能应该在内联汇编程序中放置一个标签,然后将其分支回来。

此外,指令cmpxchg %edx, %0可以对寄存器进行操作,但由于您使用的是寄存器操作数,因此无法与lock组合。要使lock cmpxchg有效,您需要将匹配参数约束从r更改为m

您可能需要查看lock cmpxchg以讨论需要内存操作数的{{1}}或here以获取没有汇编程序的螺旋锁的替代gcc实现。