【发布时间】:2009-11-17 03:11:12
【问题描述】:
我一直在搞乱一些 x86 程序集,因为它出现在我的许多课程中。特别是,我想将比较和交换 (CAS) 公开为用户函数。这是为了让我可以实现自己的锁。
我在 Intel CPU 上使用 Linux 2.6.31 和 GCC 4.1.1。
我有以下几点:
// int cmpxchg(int *dest, int expected, int update)
.globl cmpxchg
cmpxchg:
pushl %ebp
movl %esp, %ebp
// edx holds dest
movl 8(%ebp), %edx
// eax holds expected value
movl 12(%ebp), %eax
// ecx holds the new value
movl 16(%ebp), %ecx
// cmpxchg dest_addr, exp_value
// compare to %eax is implicit
lock cmpxchgl %edx, %ecx
leave
ret
这是一个 *.s 文件,我用我的驱动程序编译。当我包含该行时
lock cmpxchgl %edx, %ecx
并执行,我收到“非法指令”错误。 当我用
替换该行时 cmpxchgl %edx, %ecx
我的代码似乎运行良好。
首先,lock 有必要吗?我不确定cmpxchgl 是否自然是原子的,所以我使用lock 来确定。作为用户级程序,我什至可以使用lock 吗?
谢谢
================================================ =================
我的最终代码(对于那些将来可能会在这里徘徊的人):
// int cmpxchg(int *dest, int expected, int update)
.globl cmpxchg
cmpxchg:
pushl %ebp
movl %esp, %ebp
// edx holds dest, use eDx for Destination ;-)
movl 8(%ebp), %edx
// eax holds expected value implicitly
movl 12(%ebp), %eax
// cmpxchg dest_add, src_value
lock cmpxchgl %edx, 16(%ebp)
leave
ret
【问题讨论】:
-
你为什么不直接使用 futex 呢? (en.wikipedia.org/wiki/Futex) 只需 6 小时的组装,您无法保证此代码在所有处理器上都能正常工作。见timetobleed.com/mysql-doesnt-always-suck-this-time-its-amd
-
也许他只是想学习。重新发明轮子对生产代码不利,但却是提高编码水平的绝佳方式。