当前位置:  开发笔记 > 小程序 > 正文

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

如何解决《如何使用LOCKASM前缀读取值?》经验,为你挑选了1个好方法。

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

  lock inc     [J];

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

  xor eax, eax;
  lock add eax, [J];
  mov [JC], eax;

它在第2行引发错误.



1> GJ...:

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

编辑:如果源操作数是内存操作数,则不能将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]

写作:

MOV   [J], EAX
SFENSE

.

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