如何使用LOCK ASM前缀读取值?

Iam*_*mIC 6 x86 assembly locking thread-safety

我知道如何使用LOCK线程安全地增加一个值:

  lock inc     [J];
Run Code Online (Sandbox Code Playgroud)

但是我如何以线程安全的方式阅读[J](或任何值)?LOCK前缀不能与mov一起使用.如果我做以下事情:

  xor eax, eax;
  lock add eax, [J];
  mov [JC], eax;
Run Code Online (Sandbox Code Playgroud)

它在第2行引发错误.

GJ.*_*GJ. 9

使用XADD或MOV指令代替ADD指令!另请参阅MFENCE,LFENCESFENCE说明!

编辑:如果源操作数是内存操作数,则不能将LOCK指令与ADD指令一起使用!

来自:"英特尔®64和IA-32架构软件开发人员手册"

LOCK前缀只能作为以下指令前缀,并且只能作为目标操作数是内存操作数的指令形式:ADD,ADC,AND,BTC,BTR,BTS,CMPXCHG,CMPXCH8B,DEC,INC,NEG, NOT,OR,SBB,SUB,XOR,XADD和XCHG.如果LOCK前缀与这些指令之一一起使用且源操作数是内存操作数,则可能会生成未定义的操作码异常(#UD).如果LOCK前缀与上面列表中没有的任何指令一起使用,也会生成未定义的操作码异常.无论是否存在LOCK前缀,XCHG指令始终置位LOCK#信号

EDIT2:表格:"英特尔®64和IA-32架构软件开发人员手册,Volume3A"

8.1.1保证原子操作.Intel486处理器(以及之后的新处理器)保证始终以原子方式执行以下基本内存操作:

  • 读或写一个字节
  • 读取或写入在16位边界上对齐的字
  • 读取或写入在32位边界上对齐的双字

奔腾处理器(以及更新的处理器)保证以下额外的内存操作将始终以原子方式执行:

  • 读取或写入在64位边界上对齐的四字
  • 对适合32位
    数据总线的未缓存存储器位置的6位访问P6系列处理器
    (以及更新的处理器)
    保证以下
    额外的存储器操作将
    始终以原子方式执行:
  • 未对齐的16位,32位和64位访问缓存内存,适合
    缓存行

通过英特尔酷睿2双核处理器,英特尔酷睿双核处理器,奔腾M,奔腾4,英特尔至强,P6系列,奔腾和英特尔486,无法保证对可缓存的内存进行访问,这些内存分布在总线宽度,缓存行和页面边界上处理器.Intel Core 2 Duo,Intel Core Duo,Pentium M,Pentium 4,Intel Xeon和P6系列处理器提供总线控制信号,允许外部存储器子系统将分离访问原子化; 但是,非对齐数据访问会严重影响处理器的性能,应该避免.

所以,为了阅读我的前提是使用带有LOCK前缀的CMPXCHG指令,如:

LOCK        CMPXCHG   EAX, [J]
Run Code Online (Sandbox Code Playgroud)

写作:

MOV   [J], EAX
SFENSE
Run Code Online (Sandbox Code Playgroud)

.


归档时间:

查看次数:

5649 次

最近记录:

15 年,3 月 前