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

11

我原以为这是不可能的。但是,在这里我看到了

带有两个内存操作数的指令非常罕见

我找不到任何解释说明存在哪些指令,虽然它们很少见。那么有哪些例外呢?


我只记得movsbmovswmovsd这几个字符串指令。不过它们的内存操作数是隐式的。 - fuz
不知道为什么,但是到nasmtutorial的链接似乎指向一个空页面。 - Rudy Velthuis
2
还有一个在特蒙特的新功能叫做MOVDIR64B。 - prl
@prl:哦,太酷了,这是个好指令。我更新了我的答案。原子性超过8个字节很有趣(第一次有一个x86厂商保证了除了lock cmpxchg16b以外的任何其他东西?)在实践中,SKX可能具有64字节的载入/存储原子性,但没有干净的方法来利用更大的无锁原子对象,因为没有保证的方法来检测它。所以太糟糕了,movdir64b只能用于绕过缓存的版本中,这可能会降低在线程之间共享数据时的性能。 - Peter Cordes
解释了硬件设计的“稀缺性”,内存通过地址总线和数据总线连接到CPU,每次只能读/写单个值,通过设置地址总线线路以包含所需值的地址和数据总线以要写入的值(或等待内存芯片将数据总线设置为读取的值)。因此,任何两个内存操作数都是(曾经)按顺序实现的。现在的CPU更加复杂,内存访问被分层在缓存系统下,但单内存操作数设计似乎足够强大,不需要改变这种方式。 - Ped7g
@Ped7g,那不是我想要的,但我可以看出解释会解决它。 - Evan Carroll
1个回答

24
我找不到任何解释罕见性的内容。
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]:从[mem]读取新的RIP,将返回地址推送到堆栈上。
  • movsb/w/d/q:读取DS:(E)SI,将其写入ES:(E)DI(或在64位模式下为RSI和RDI)。两者都是隐含的;只有DS段寄存器可以被覆盖。可与rep一起使用。
  • cmpsb/w/d/q:读取DS:(E)SIES:(E)DI(或在64位模式下为RSI和RDI)。两者都是隐含的;只有DS段寄存器可以被覆盖。可与repe/repne一起使用。

  • MPX bndstx mib, bnd:"将边界存储在bnd中,并将mib的索引寄存器中的指针值存储到使用mib的基地址进行地址转换的边界表项(BTE)中。" 操作部分显示了一次加载和存储操作,但我对MPX知之甚少,无法理解。

  • movdir64b r16/r32/r64, m512。拥有自己的特性位,在即将推出的Tremont(Goldmont Plus Atom的继任者)中可用。将64字节作为直接存储(WC)以64字节写原子性从源内存地址移动到目标内存地址。目标操作数是来自ModRM的(对齐的原子)es:/r,源是(非对齐非原子)来自ModRM的/m

    使用写合并进行存储,请参阅描述。这是x86 CPU供应商首次保证8字节之外的原子性,而不需要使用lock cmpxchg16b。但不幸的是,它实际上并不适合多线程,因为它强制执行类似于NT的缓存驱逐/旁路行为,因此其他核心将不得不从DRAM中读取它,而不是从共享的外部缓存中读取。

AVX2 gather 和 AVX512 scatter 指令是有争议的。它们显然会执行多次加载和存储操作,但所有指针都来自于一个 SIMD 向量(以及一个标量基地址)。

我没有计算诸如 pushafldenvxsaveopt, iret 或嵌套级别 > 1 的 enter 等进行多个连续块的存储或加载的指令。

我也不会计算 ins / outs 字符串指令,因为它们将内存复制到 / 从 I/O 空间。I/O 空间不是内存。

我没有查看 http://felixcloutier.com/x86/index.html 上的 VMX 或 SGX 指令列表,只是主要列表。我不认为我错过了任何内容,但我当然可能有所疏漏。


1
有没有任何指令具有4个显式操作数?因为这个网站(https://www.felixcloutier.com/x86/index.html)在所有指令的操作数表中保留了4列。 - Sourav Kannantha B
@SouravKannanthaB:是的,vpblendvb/vblendvps/pd ,但仍然只能使用一个内存。x86 CPU有什么样的地址指令?请注意,https://www.felixcloutier.com/x86/ 只是从英特尔的PDF手册中提取的。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接