哪些 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
,或者字符串指令 movs
和 cmps
.
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)SI
和 ES:(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 向量(和一个标量基)。
我没有计算像 pusha
、fldenv
、xsaveopt
、iret
或 enter
这样的嵌套级别 > 1 的指令存储或加载到连续块。
我也没有计算 ins
/ outs
字符串指令,因为它们复制内存 to/from I/O space。 I/O space 不是内存。
我没有看 http://felixcloutier.com/x86/index.html 上的 VMX 或 SGX 说明,只看主列表。我不认为我错过了任何一个,但我当然可以。
我以为是零。但是,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
,或者字符串指令 movs
和 cmps
.
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)SI
和ES:(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 向量(和一个标量基)。
我没有计算像 pusha
、fldenv
、xsaveopt
、iret
或 enter
这样的嵌套级别 > 1 的指令存储或加载到连续块。
我也没有计算 ins
/ outs
字符串指令,因为它们复制内存 to/from I/O space。 I/O space 不是内存。
我没有看 http://felixcloutier.com/x86/index.html 上的 VMX 或 SGX 说明,只看主列表。我不认为我错过了任何一个,但我当然可以。