当前位置:  开发笔记 > 运维 > 正文

ASM中的非法指令:锁定cmpxchg dest,src

如何解决《ASM中的非法指令:锁定cmpxchgdest,src》经验,为你挑选了1个好方法。

我一直在讨论一些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

DigitalRoss.. 7

你需要 cmpxchgl %edx, (%ecx)

除非目标是内存操作数,否则此操作没有意义,但该指令允许寄存器目标.如果指令使用寄存器模式,CPU将发生故障.

我尝试过,你的代码使用内存操作数.我不知道你是否意识到这一点,但这个序列(带寄存器目的地)有一个流行的名字:"f00fc7c8 bug"或" F00F bug ".在Pentium时代,这是一个"HCF"(停止和着火)或"杀手捅"指令,因为它会产生一个例外,由于总线被锁定而无法服务,并且它可以从用户调用模式.我认为可能存在操作系统级别的软件解决方法.



1> DigitalRoss..:

你需要 cmpxchgl %edx, (%ecx)

除非目标是内存操作数,否则此操作没有意义,但该指令允许寄存器目标.如果指令使用寄存器模式,CPU将发生故障.

我尝试过,你的代码使用内存操作数.我不知道你是否意识到这一点,但这个序列(带寄存器目的地)有一个流行的名字:"f00fc7c8 bug"或" F00F bug ".在Pentium时代,这是一个"HCF"(停止和着火)或"杀手捅"指令,因为它会产生一个例外,由于总线被锁定而无法服务,并且它可以从用户调用模式.我认为可能存在操作系统级别的软件解决方法.

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有