1
7
最简单的方法可能是 compiler intrinsic 喜欢 _InterlockedCompareExchange() . 它看起来像一个函数,但实际上是编译器中的一个特例,可以归结为一个单独的机器操作。在MSVC x86内部函数的情况下,它也可以作为读/写界限,但在其他平台上不一定如此。(例如,在PowerPC上,您需要显式地发出 lwsync 限制内存重新排序。) 一般来说,在许多常见的系统中,比较和交换操作通常只对其所接触的一个地址执行原子事务。其他的内存访问可以重新排序,在多核系统中,您交换的内存地址以外的内存地址可能在核心之间不一致。 |
2
7
你可以使用
例如。
或
这将比较EAX寄存器中的值与EBX寄存器中存储的地址处的值,并将EDX寄存器中的值存储到该位置(如果它们相同),否则它将EBX寄存器中存储的地址处的值加载到EAX中。 您需要486或更高版本才能使用此指令。 |
3
4
如果整数值为64位,则在IA32 x86下使用cmpxchg8b 8字节比较和交换。 变量必须对齐8字节。
|
4
3
如果在原子处理器指令中省略锁前缀,则跨多处理器环境的原子操作将 不能保证 .
如果没有锁前缀,操作将保证不会被当前处理器/内核上的任何事件(中断)中断。 |
5
2
有趣的是,有些处理器不提供比较交换,而是提供一些其他指令(“加载链接”和“条件存储”),这些指令可用于合成不幸命名的比较和交换(名称听起来应该类似于“比较交换”,但实际上应该称为“比较和存储”)因为它进行比较,所以存储值是否匹配,并指示值是否匹配以及是否执行了存储)。指令不能综合比较交换语义(在比较失败时提供读取的值),但在某些情况下可以避免比较交换存在的ABA问题。许多算法都是用“CAS”操作来描述的,因为它们可以在两种类型的CPU上使用。 一条“加载链接”指令告诉处理器读取一个内存位置,并以某种方式观察它是否可能被写入。“条件存储”指令指示处理器仅当自上次“加载链接”操作以来没有任何东西可以写入内存位置时才写入内存位置。注意,确定可能是悲观的;例如,处理中断可能会使“加载链接/条件存储”序列失效。同样地,在多处理器系统中,LL/CS序列可能被另一个CPU访问与被监视的位置在同一缓存线上的位置而失效,即使被监视的实际位置没有被触摸。在典型的用法中,LL/CS与retry循环一起使用,这样错误的失效可能会稍微慢一点,但不会造成太大的麻烦。 |
Anon. · 用汇编语言解释这一行? 6 年前 |
wangt13 · 如何使用VMX暂停和恢复VM 6 年前 |
Kay · Skylake和更新的环形巴士 6 年前 |
Kadir · Intel芯片上的半精度浮点算法 6 年前 |
Some_Dude · x86汇编牛顿平方根算法寄存器为1#IND 6 年前 |