Lor*_*ndy 14 x86 assembly prefix
为了理解Bulldozer为什么不合格,我一直在关注Agner Fog的优秀微架构书,在第178页的推土机下它有这一段.
最多三个前缀的指令可以在一个时钟周期内解码.对于具有三个以上前缀的指令,会有非常大的惩罚.具有4-7前缀的指令需要额外14-15个时钟周期才能进行解码.带有8-11前缀的指令需要额外增加20-22个时钟周期,带有12-14前缀的指令需要额外增加27-28个时钟周期.因此,不建议使用超过三个前缀来延长NOP指令.此规则的前缀计数包括操作数大小,地址大小,段,重复,锁定,REX和XOP前缀.三字节VEX前缀计为一,而两字节VEX前缀不计.转义码(0F,0F38,0F3A)不计算在内.
当我搜索前缀时,我的技术定义远远超出了我的能力.或者,建议每条指令限制为4条,这与上述摘录相冲突.
因此,简单来说,有人可以解释他们是什么/做什么以及为什么你可能想要将多达14+用于指令而不是分解?
Jes*_*ter 11
通常情况下,您可以根据需要使用尽可能多的指令和操作数来确定.汇编程序会自动发出一些前缀,而其他人则可以手动使用.
他们提到的情况是多字节NOP,传统上用于对齐填充,其中的想法是使用单个但适当长的指令来节省资源.显然,事实证明,使用更多的前缀只是为了保持单个指令可能比使用两个前缀更少的指令更糟糕.
此规则的前缀计数包括操作数大小,地址大小,段,重复,锁定,REX和XOP前缀.三字节VEX前缀计为一,而两字节VEX前缀不计.
例子:
mov ax, [foo]编码mov eax, [foo]与前缀相同但编码方式相同66hmov [eax], foo编码mov [rax], foo与前缀相同67h(在64位模式下)mov [fs:eax], foo编码mov [eax], foo与前缀相同但编码相同64h.rep cmpsb编码cmpsb与前缀相同但与前缀相同f3hlock add [foo], 1编码add [foo], 1与前缀相同但编码相同f0hadd rax, 1编码add eax, 1与前缀相同但编码相同48hadd r8d, 1相同add eax, 1但带有前缀41h“四个前缀”协议来自“前缀组”:
您可以重复前缀,但不能(可以,但是行为未定义)可以使用同一组中的多个不同前缀。尽管这仅适用于第1组和第2组,但其他各组中只有1件东西。
类似的东西66 66 66 66 66 66 66 66 90是有效的(但可能会很慢地解码)。2E 3E 00 00(混合细分替代)不是。
当必须执行字节时,堆栈前缀对于代码对齐很有用,这与填充不同,nop这样做不会花费执行时间。一次使用太多可能会花费解码时间。