CMPXCHG8B, CMPXCHG16B

比较和交换字节

stableVMJITAOTinstruction

编码

操作码指令Op/En64 位兼容/传统说明
0F C7 /1CMPXCHG8B m64M有效valid*将 EDX:EAX 与 m64 相比较,如果相等,设置 ZF 并加载 ECX:EBX 成为 m64. Else,清除 ZF 并加载 m64 成为 EDX:EAX.
REX.W + 0F C7 /1CMPXCHG16B m128M有效不可编码将 RDX:RAX 与 m128 相比较,如果相等,设置 ZF 并加载 RCX:RBX 成为 m128. Else,清除 ZF 并加载 m128 成为 RDX:RAX.

操作数编码

每个模式对应上表 Op/En 列的一个取值,说明各操作数按书写顺序分别编码在指令的哪个字段,以及指令对它是读、是写还是两者兼有。

M

  1. modrm.rm lectura y escrituraModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移

实测开销

正在从 arch-data 加载实测数据...

涉及的标志位

说明

将EDX:EAX中的64位值(或128位值为RDX:RAX,如果操作数大小是128位)与操作数(目标操作数)进行比较. 如果数值相等,则以ECX:EBX的64位值(或以RCX:RBX的128位值)存储在目标操作数. 否则,目标操作数中的值会被加载到EDX:EAX(或RDX:RAX)中. 目标操作数是一个8字节的内存位置(或16字节的内存位置,如果操作数大小是128位). 对于EDX:EAX和ECX:EBX注册对,EDX和ECX包含高序32位,EAX和EBX包含64位值的低序32位. 对于RDX:RAX和RCX:RBX注册对,RDX和RCX包含高序64位,RAX和RBX包含128位值的低序64位.

此指令可用 LOCK 前缀来允许指令在原子上执行. 为了简化处理器总线的接口,目标操作数在不考虑比较结果的情况下得到一个写周期. 如果比较失败, 目标操作数 会被写回;否则, 源操作数 会被写回目的地. (处理器从不产生锁定的读数,而不产生锁定的写字).

在64位模式下,默认操作大小为64位. 使用REX.W前缀将操作提升到128位. 注意CMPXCHG16B要求目的地(memory)操作数为16字节对齐. 参见本节开头的汇总图,用于编码数据和限制. 关于表示CMPX-CHG16B的CPUID旗的信息,参见Intel(R)64和IA-32架构软件开发者手册第1卷第21章.

IA-32 架构兼容性

这种指令编码在英特尔处理器上不比Pentium处理器早得到支持.

行动

IF (64-Bit Mode and OperandSize = 64)
    THEN
          TEMP128 := DEST

        IF (RDX:RAX = TEMP128)

                THEN
                      ZF := 1;
                      DEST := RCX:RBX;

                ELSE
                      ZF := 0;
                      RDX:RAX := TEMP128;
                      DEST := TEMP128;
                      FI;

          FI
    ELSE

          TEMP64 := DEST;

        IF (EDX:EAX = TEMP64)

                THEN
                      ZF := 1;
                      DEST := ECX:EBX;

                ELSE
                      ZF := 0;
                      EDX:EAX := TEMP64;
                      DEST := TEMP64;
                      FI;

          FI;
FI;

受影响的旗帜

若目标操作数和EDX:EAX等值,则设置ZF旗;否则清除. CF、PF、AF、SF和OF旗帜不受影响。

异常

保护模式
#UD如果目的地不是内存操作数的话.
#GP(0)如果目的地位于不可写入的区段中。如果内存操作数的有效地址位于CS、DS、ES、FS或GS区段限制之外。如果DS、ES、FS或GS登记簿包含NULL 段选择子。
#SS(0)如果 内存操作数 有效地址在 SS 段限制之外. #PF(fault-code) 如果 页面错误 发生.
#AC(0)如果启用了对齐检查,并且在当前特权级别为3时会给出不对齐的内存引用.
实地址模式
#UD如果目标操作数不是内存位置的话.
#GP如果内存操作数的有效地址在CS,DS,ES,FS或GS段限制之外.
#SS如果 内存操作数 的有效地址在 SS 段限制之外。
虚拟 8086 模式
#UD如果目标操作数不是内存位置的话.
#GP(0)如果内存操作数的有效地址在CS,DS,ES,FS或GS段限制之外.
#SS(0)如果 内存操作数 有效地址在 SS 段限制之外. #PF(fault-code) 如果 页面错误 发生.
#AC(0)如果启用对齐检查, 并使用不对齐的内存引用 。
兼容模式
与保护模式中的例外相同.
64 位模式
#SS(0)如果引用SS部分的内存地址是非冠状的.
#GP(0)如果内存地址是非冠状的。如果 内存操作数 用于 CMPXCHG16B 的 内存操作数 不在16字节边界上对齐。如果 CPUID.01H: ECX.CMPXCHG16B[13] = 0 。
#UD如果 目标操作数 不是 内存位置. #PF(fault-code) 如果发生 页面错误.
#AC(0)如果启用了对齐检查,并且在当前特权级别为3时会给出不对齐的内存引用.

来源