我以为是零。但是,我看到这里,
具有两个内存操作数的指令极为罕见
我找不到任何可以解释存在哪些指令的东西,虽然很少见。有哪些例外?
我找不到任何可以解释这种稀有性的东西。
一条 x86 指令最多可以有一个 ModR/M + SIB + disp0/8/32。所以有两个显式内存操作数的指令为零。
x86 内存-内存指令都有至少一个隐式内存操作数,其位置被烘焙到操作码中,例如push
访问堆栈或字符串指令movs
和cmps
.
有哪些例外?
我将[mem]
用来表示 ModR/M 寻址模式,它可以是[rdi]
、[RIP+whatever]
、[ebx+eax*4+1234]
或任何你喜欢的。
push [mem]
:读取[mem]
,写入隐式[rsp]
(更新后rsp
)。pop [mem]
call [mem]
: 从 中读取新的 RIP [mem]
,将返回地址压入堆栈。movsb/w/d/q
: 读取DS:(E)SI
、写入ES:(E)DI
(或在 64 位模式下 RSI 和 RDI)。两者都是隐含的;只有DS
段 reg 是可覆盖的。可与rep
.cmpsb/w/d/q
:读取DS:(E)SI
和ES:(E)DI
(或在 64 位模式下 RSI 和 RDI)。两者都是隐含的;只有DS
段 reg 是可覆盖的。可与repe
/一起使用repne
。
MPX bndstx mib, bnd
:“将 bnd 中的边界和 mib 索引寄存器中的指针值存储到绑定表条目 (BTE),并使用 mib 的基址进行地址转换。” 操作部分显示了一个负载和一个存储,但我对 MPX 的了解还不够,无法理解它。
movdir64b r16/r32/r64, m512
. 有自己的功能位,在即将推出的 Tremont(Goldmont Plus Atom 的继任者)中可用。将 64 字节作为具有 64 字节写入原子性的直接存储 (WC) 从源内存地址移动到目标内存地址。目标操作数是来自 ModRM 的(对齐的原子)es:
/r
,源是来自 ModRM 的(未对齐的非原子)/m
。
对存储使用写组合,请参阅描述。这是任何 x86 CPU 供应商第一次保证在lock cmpxchg16b
. 但不幸的是,它实际上并不适合多线程,因为它会强制执行类似 NT 的缓存驱逐/绕过行为,因此其他内核将不得不从 DRAM 而不是共享的外部缓存中读取它。
AVX2 聚集和 AVX512 分散指令值得商榷。它们显然进行了多次加载/存储,但所有指针都来自一个 SIMD 向量(和一个标量基数)。
我不计算诸如pusha
, fldenv
, xsaveopt
,之类的指令iret
,或者enter
嵌套级别 > 1 的指令,这些指令执行多个存储或加载到一个连续的块。
我也没有计算ins
/outs
字符串指令,因为它们将内存复制到/从 I/O 空间。I/O 空间不是内存。
我没有查看http://felixcloutier.com/x86/index.html上的 VMX 或 SGX 指令,只是主要列表。我不认为我错过了任何,但我当然可以。