我知道如何使用LOCK线程安全地增加一个值:
lock inc [J];
但是我如何以线程安全的方式阅读[J](或任何值)?LOCK前缀不能与mov一起使用.如果我做以下事情:
xor eax, eax; lock add eax, [J]; mov [JC], eax;
它在第2行引发错误.
使用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
.