下面的内联汇编代码有什么问题吗? 我在运行函数 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");
最佳答案
问题出在你的分支上;通常(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
。
您可能想看一下here有关需要内存操作数的lock cmpxchg
的讨论或 here用于无需汇编器的自旋锁的替代 gcc 实现。
关于内联汇编 对于 "Illegal instruction (core dumped)"我该怎么办,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12450887/