哪些 x86 指令需要两个(或更多)内存操作数?

What x86 instructions take two (or more) memory operands?

我以为是零。但是,I see here,

Instructions with two memory operands are extremely rare

我找不到任何解释说明存在的说明,尽管很少见。有哪些例外情况?

I can't find anything that explains the rarity.

一个x86指令最多可以有一个ModR/M + SIB + disp0/8/32。所以有两个 explicit 内存操作数的指令为零。

x86 内存-内存指令都至少有一个 隐式 内存操作数,其位置已写入操作码,例如访问堆栈的 push,或者字符串指令 movscmps.

What are the exceptions?

我将使用 [mem] 表示 ModR/M 寻址模式,可以是 [rdi][RIP+whatever][ebx+eax*4+1234] 或任何您喜欢的寻址模式。

  • push [mem]:读取[mem],写入隐式[rsp](更新rsp后)。
  • pop [mem]
  • call [mem]:从 [mem] 读取一个新的 RIP,将 return 地址压入堆栈。
  • movsb/w/d/q:读取DS:(E)SI,写入ES:(E)DI(或在 64 位模式下的 RSI 和 RDI)。两者都是隐式的;只有 DS 段 reg 是可覆盖的。可用于 rep.
  • cmpsb/w/d/q:读取 DS:(E)SIES:(E)DI(或在 64 位模式下 RSI 和 RDI)。两者都是隐式的;只有 DS 段 reg 是可覆盖的。可用于 repe / repne.

  • MPX bndstx mib, bnd: "Store the bounds in bnd and the pointer value in the index register of mib to a bound table entry (BTE) with address translation using the base of mib." 操作部分显示了一个加载和一个存储,但我对 MPX 了解不够,无法理解它。

  • movdir64b r16/r32/r64, m512. Has its own feature bit, available in upcoming Tremont(Goldmont Plus Atom 的继任者)。将具有 64 字节写入原子性的 64 字节作为直接存储 (WC) 从源内存地址移动到目标内存地址。目标操作数是来自 ModRM 的(对齐原子)es: /r,源是来自 ModRM 的(未对齐非原子)/m

    对store使用write-combining,见说明。这是 x86 CPU 供应商首次保证 lock cmpxchg16b 之外的原子性大于 8 个字节。但不幸的是,它实际上并不适合多线程,因为它强制执行类似 NT 的缓存 eviction/bypass 行为,因此其他内核将不得不从 DRAM 而不是共享的外部缓存中读取它。

AVX2 gather 和 AVX512 scatter 指令值得商榷。他们显然进行了多次加载/存储,但所有指针都来自一个 SIMD 向量(和一个标量基)。

我没有计算像 pushafldenvxsaveoptiretenter 这样的嵌套级别 > 1 的指令存储或加载到连续块。

我也没有计算 ins / outs 字符串指令,因为它们复制内存 to/from I/O space。 I/O space 不是内存。

我没有看 http://felixcloutier.com/x86/index.html 上的 VMX 或 SGX 说明,只看主列表。我不认为我错过了任何一个,但我当然可以。